我对浮点数的表示方式有些了解,但恐怕还不够。
普遍的问题是:
对于给定的精度(出于我的目的,以10为基数的精确小数位数),对于16位,32位和64位IEEE-754系统,可以表示什么数字范围?
具体来说,我只对精度为+/- 0.5(一个位)或+/- 0.0005(千个位)的16位和32位数字范围感兴趣。
Answers:
对于给定的IEEE-754浮点数X,如果
2^E <= abs(X) < 2^(E+1)
那么从X到下一个最大可表示浮点数(epsilon)的距离为:
epsilon = 2^(E-52) % For a 64-bit float (double precision)
epsilon = 2^(E-23) % For a 32-bit float (single precision)
epsilon = 2^(E-10) % For a 16-bit float (half precision)
上面的等式允许我们计算以下内容:
对于半精度...
如果您希望精度为+/- 0.5(或2 ^ -1),则数字的最大大小为2 ^ 10。大于此值且浮点数之间的距离大于0.5。
如果您希望精度为+/- 0.0005(约2 ^ -11),则数字的最大大小可以为1。任何大于此数字的值,且浮点数之间的距离均大于0.0005。
对于单精度...
如果您希望精度为+/- 0.5(或2 ^ -1),则数字的最大大小为2 ^ 23。大于此值且浮点数之间的距离大于0.5。
如果您希望精度为+/- 0.0005(大约2 ^ -11),则数字的最大大小为2 ^ 13。大于此值且浮点数之间的距离大于0.0005。
对于双精度...
如果希望精度为+/- 0.5(或2 ^ -1),则数字的最大大小为2 ^ 52。大于此值且浮点数之间的距离大于0.5。
如果您希望精度为+/- 0.0005(大约2 ^ -11),则数字的最大大小为2 ^ 42。大于此值且浮点数之间的距离大于0.0005。
对于浮点整数(我将以IEEE双精度的方式给出答案),每个介于1和2 ^ 53之间的整数都可以精确表示。超出2 ^ 53时,可精确表示的整数通过增加2的幂进行间隔。例如:
无法精确表示的整数会四舍五入为最接近的可表示整数,因此最坏的情况下,四舍五入是可表示整数之间的间距的1/2。
Peter R指向MSDN ref的链接所引用的精度可能是一个很好的经验法则,但是当然现实要复杂得多。
“浮点数”中的“点”是二进制点而不是小数点这一事实有可能破坏我们的直觉。经典示例是0.1,它只需要十进制的一位数字精度,而根本不能完全用二进制表示。
如果您有一个周末要消磨时间,请查看每位计算机科学家应了解的有关浮点算法的知识。您可能会对“精度”和“二进制到十进制转换”部分特别感兴趣。
首先,IEEE-754-2008和-1985都没有16位浮点数。但它是建议的加法运算,具有5位指数和10位分数。IEE-754使用专用的符号位,因此正负范围相同。另外,小数前面有一个隐含的1,因此您会得到一个额外的位。
如果要将精度表示在某个位置(如可以表示每个整数),则答案非常简单:指数将小数点移至分数的右端。因此,10位小数将使您获得±2 11。
如果要在小数点后一位,则放弃前一位,所以您有±2 10。
单精度具有23位小数,因此您将具有±2 24个整数。
小数点后需要多少位精度完全取决于您正在执行的计算以及您正在执行的计算。
注意(1 +分数)。正如@bendin指出的那样,使用二进制浮点数不能表示简单的十进制值,例如0.1。这意味着您可以通过多次简单的加法或调用诸如截断之类的方法来引入舍入错误。如果您对任何一种精度都感兴趣,唯一的方法就是使用定点十进制,它基本上是一个可缩放的整数。