我对浮点数的表示方式有些了解,但恐怕还不够。
普遍的问题是:
For a given precision (for my purposes, the number of accurate decimal places in base 10), what range of numbers can be represented for 16-, 32- and 64-bit IEEE-754 systems?
具体来说,我只对精度为+/- 0.5(一个位)或+/- 0.0005(千个位)的16位和32位数字范围感兴趣。
@bendin:是的,它存在。 zh.wikipedia.org/wiki/Half_precision_floating-point_format
相关:浮点精度是可变的还是不变的?
@bendin甚至存在8位或更少的浮点数,并且经常在计算机科学课程中教授。 它也用于ARM构造编码中。 10、11、14位浮点数也存在
对于给定的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。
以米计,这意味着分别以1m和1mm的精度,半精度允许1km和1m,单精度允许8Mm和8km,而双精度允许4Pm和4Tm。
对于浮点整数(我将以IEEE双精度的方式给出答案),每个介于1和2 ^ 53之间的整数都可以精确表示。超出2 ^ 53时,可精确表示的整数通过增加2的幂进行间隔。例如:
可以精确表示2 ^ 53 + 2和2 ^ 54之间的每个第二整数。
可以精确表示2 ^ 54 + 4和2 ^ 55之间的每4个整数。
可以精确表示2 ^ 55 + 8和2 ^ 56之间的每8个整数。
可以准确表示2 ^ 56 + 16和2 ^ 57之间的每16个整数。
可以准确表示2 ^ 57 + 32和2 ^ 58之间的每个第32个整数。
可以精确表示2 ^ 58 + 64和2 ^ 59之间的每64个整数。
可以准确表示2 ^ 59 + 128和2 ^ 60之间的每128个整数。
可以精确表示2 ^ 60 + 256和2 ^ 61之间的每256个整数。
可以精确表示2 ^ 61 + 512和2 ^ 62之间的每512个整数。
。
。
。
无法精确表示的整数会四舍五入为最接近的可表示整数,因此最坏的情况下,四舍五入是可表示整数之间的间距的1/2。
Peter R指向MSDN ref的链接所引用的精度可能是一个很好的经验法则,但是当然现实要复杂得多。
"浮点数"中的"点"是二进制点而不是小数点这一事实有可能破坏我们的直觉。经典示例是0.1,它只需要十进制的一位数字精度,而根本不能完全用二进制表示。
如果您有一个周末要消磨时间,请查看每位计算机科学家应该了解的有关浮点算法的知识。您可能会对"精度"和"二进制到十进制转换"部分特别感兴趣。
首先,IEEE-754-2008和-1985都没有16位浮点数。但它是建议的加法运算,具有5位指数和10位分数。 IEE-754使用专用的符号位,因此正负范围相同。另外,小数前面有一个隐含的1,因此您会得到一个额外的位。
如果要将精度表示在某个位置,例如可以表示每个整数,则答案非常简单:指数将小数点移至分数的右端。因此,一个10位的分数等于±211。
如果要在小数点后一位,则放弃它的前一位,所以您有±210。
单精度具有23位小数,因此您将具有±224个整数。
小数点后所需的精度位数完全取决于您正在执行的计算以及您正在执行的计算。
210 = 1,024
211 = 2,048
223 = 8,388,608
224 = 16,777,216
253 = 9,007,199,254,740,992(双精度)
2113 = 10,384,593,717,069,655,257,060,992,658,440,192(四精度)
也可以看看
双精度
半精度
参见IEEE 754-1985:
注意(1 +分数)。正如@bendin指出的那样,使用二进制浮点数不能表示简单的十进制值,例如0.1。含义是,您可以通过多次进行简单加法或调用诸如截断之类的方法来引入舍入错误。如果您对任何一种精度都感兴趣,唯一的方法就是使用定点十进制,它基本上是一个可缩放的整数。
我花了相当长的时间才弄清楚,在Java中使用double时,我并没有在计算上损失很多精度。实际上,浮点具有非常好的以相当合理的精度表示数字的能力。我失去的精度是立即将用户键入的十进制数字转换为本机支持的二进制浮点表示形式。我最近开始将所有数字转换为BigDecimal。 BigDecimal不是浮点数或双精度数,因此它在代码中要处理的工作要多得多,因为它不是原始类型之一。但另一方面,我将能够准确表示用户输入的数字。
如果我正确理解您的问题,则取决于您的语言。
对于C#,请查看MSDN参考。浮点数的精度为7位,双精度为15-16位。
实际上,IEEE-754定义了精度,因此它不应特定于语言。