我一直在努力寻找如何计算浮点数/双精度范围数字-3.402823e38..3.402823e38和-1.79769313486232e308..1.79769313486232e308。
对于int32,您会进行2 ^ 32 = 4294967296/2的运算,从而得到-2147483648到2147483647的范围。那么我该如何确定浮点数和双精度数的精度数字呢?我认为我正在搜索错误的术语,因为没有任何结果出现。
我一直在努力寻找如何计算浮点数/双精度范围数字-3.402823e38..3.402823e38和-1.79769313486232e308..1.79769313486232e308。
对于int32,您会进行2 ^ 32 = 4294967296/2的运算,从而得到-2147483648到2147483647的范围。那么我该如何确定浮点数和双精度数的精度数字呢?我认为我正在搜索错误的术语,因为没有任何结果出现。
好的,实际上这两种类型看起来都像以下内容:
[sign] [exponent] [mantissa]
用以下形式表示数字:
[符号] 1.[尾数] × 2[指数]
其中指数和尾数的大小各不相同。对于 float
类型,指数有 8 位宽度,而 double
类型则有11位宽度。此外,指数使用无符号表示,具有一个称为偏移量的值,float
为127,double
为1023。这将使得 float
的指数范围为 -126 至 127,double
的指数范围为 -1022 至 1023。
指数是2某个数的指数,因此当计算2127时,您将获得1.7×1038,这将使您处于大约 float
最大值的范围内。类似地,double
可以获得9×10307。
显然,这些数字并不完全符合我们的期望。这就是尾数发挥作用的地方。尾数表示一个始终以“1”开头的规格化二进制数(这就是规格化部分)。其余部分就是小数点后的数字。由于最大尾数近似为二进制中的1.111111111...,几乎等于2,因此我们得到了约为3.4×1038的 float
最大值和约为1.79×10308的 double
最大值。
[编辑 2011-01-06] 正如下面问题所述(以及问题下方),精确公式如下:
其中 e 是指数位数,p 是尾数位数,包括前面提到的隐式位(由于规格化而产生)。该公式再次复制了我们上面看到的结果,但现在更精确了。第一个因子 22e − 1 是最大指数,乘以二(我们将此保存在第二个因子中)。第二个因子是我们可以表示的最大的小于一的数字。我曾经说过这个数字几乎是两个。由于在这个公式中我们将指数扩大了两倍,所以我们需要考虑这一点,现在得到的数字几乎是一。希望不会太困惑。
无论如何,对于 float
(e=8,p=24),我们得到精确值:340282346638528859811704183484516925440,大约为3.4×1038。对于 double
(e=10,p=53),我们得到的精确值为:179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144
1. 1 0 1 1
↑ ↑ ↑ ↑ ↑
2^0 2^-1 2^-2 2^-3 2^-4
= = = = =
1 0.5 0.25 0.125 0.0625
因此,double
尾数中的最后一位代表大约2.2×10−16或2−52的值,所以如果指数为1,则这是我们可以添加到该数字的最小值-使得double
精度在16个十进制数字左右。同样适用于具有大约七个数字的float
。
我已经从各个方面(虽然不是全部)讨论了浮点格式。这个答案可能会对你有所帮助:https://stackoverflow.com/questions/4851671/printing-double-without-losing-precision
计算并不那么容易。这是因为浮点数和双精度数的实现方式不同。它们都被分成两部分:一部分用于基数,另一部分用于指数。我认为浮点数将24位分配给基数,8位分配给指数。但我对此并不确定!尽管如此,我将基于这个事实进行进一步的计算和假设,所以这些计算可能都是错误的,但它们说明了正确的原则。这些规格也可能因语言而异,即使有标准规定它们不应该。但在编程时不能把任何事情视为理所当然 :p
这意味着基数可以在-8388608和8388607之间,指数可以在-128和127之间。
然后当使用数字时,计算机会像这样思考:
基数 * 10^指数
这导致最大可能的数字是8388607 * 10 ^ 127,这将是...很多。但它将包含120个零,因为它不能指定超过7个数字。
随着数字的增长,数字的精度会降低。这意味着您的问题格式不正确 ;) 只有在您知道需要多少个正确小数位数时,才能为浮点数指定有效范围。如果您需要2个保证准确小数位的可能性,则浮点数的范围为-83885至83885。
浮点类型可以表示从大约1.5×10−45到3.4×1038的值,精度为7位数字。
双精度类型可以表示从大约5.0×10−324到1.7×10308的值,精度为15-16位数字。
http://msdn.microsoft.com/en-us/library/aa691146%28v=vs.71%29.aspx