实际上是:3.4028234664×10 ^ 38
我正在编写一个函数,该函数的字符串包含单个浮点值,例如'3.14159'。
[我想做的是评估此浮点数是否超出了有符号的32位浮点数(也是64位,但现在让我们忘记它的边界)。
由于浮点精度问题,我想使用Decimal
对象进行比较。
如何创建具有最大有符号32位浮点数的Decimal
?
这将用于比较。
[略过此维基百科文章:https://en.wikipedia.org/wiki/Single-precision_floating-point_format
...报告有23个系数位,8个指数位和1个符号位,我编写了以下代码。
from decimal import Decimal
def is_single(value):
d_value = Decimal(value)
_23bit_max_bin = '1' * 23 # '11111111111111111111111'
_23bit_max_dec = int(_23bit_max_bin, 2) # 8388607
_coeffient_tuple = tuple([int(d) for d in str(_23bit_max_dec)]) # (8, 3, 8, 8, 6, 0, 6)
_exponent_bin = '1' * 8 # '11111111'
_exponent_dec = int(_exponent_bin, 2) # 255
_dec_tuple = (0, _coeffient_tuple, _exponent_dec) # (1, (8, 3, 8, 8, 6, 0, 6), 254)
max_single_size = Decimal(_dec_tuple) # Decimal('8.388607E+261')
print(max_single_size) # Decimal('8.388607E+261')
return d_value < max_single_size
is_single('3.14159')
...我的希望是,我可以取系数和指数的最大二进制值,将它们转换为十进制值,然后使用结果创建一个Decimal
对象。
问题是,结果值似乎与同一维基百科页面上报告的值相似,即8.388607E+261
(我的值)与1.1754942107 ×10−38
(维基)不一样
我感觉好像在丢失某些东西……也许为时已晚?
…签名的32位浮点数的边界…
float
中的可表示数的范围是-∞到+∞,因此所有有限数都在该范围内。但是我想您想考虑float
类型的有限范围,而不是整个范围。
_23bit_max_bin = '1' * 23 # '11111111111111111111111'
_23bit_max_dec = int(_23bit_max_bin, 2) # 8388607
这将为您提供float
编码的有效字段的最大值,将其解释为二进制整数。那不是所表示有效数字的最大值。
假设指数字段既不是全零也不是全1,则表示的有效位数是其二进制数字为“ 1”后跟“。”的数字。随后是有效字段的位。因此,最大有效位数为1.11111111111111111111111111 2 = 2 1-2 − 23。
exponent_bin = '1' * 8 # '11111111'
这将为您提供指数字段的最大值。但是,指数字段的最大值用于编码无穷大和NaN,而不是有限的数字。用于有限数的指数字段的最大值为11111110 2(254 10)。此外,所表示的指数是指数字段的值(解释为二进制整数)减去127。因此,最大指数为254-127 = 127。
_dec_tuple = (0, _coeffient_tuple, _exponent_dec) # (1, (8, 3, 8, 8, 6, 0, 6), 254)
[使用254作为10的指数。float
格式的指数为2的指数。
float
中可表示的最大有限值是最大有效值乘以2与最大指数的幂,因此为(2 1-2 − 23)•2 127 = 2 128-2 104 =340282346638528859811704183484516925440。我们将其称为M。
但是,在确定十进制数字是否在界限内时,应考虑是否要考虑:
float
时,四舍五入将产生-M在后一种情况下,在四舍五入到最接近的模式下,您想要的限制为2 128
通常,如果精度为p
(有效字段具有p-1位),而指数字段具有w位,则指数偏差为2 w] > -1-1,最大指数相同,并且最大可表示的有限值为(2-2 1-p)•2 2 w- 1 − 1 =(1-2 -p)•2 2 w − 1。实际上是:3.4028234664×10 ^ 38
尝试查找以下数字:
2 ^ 128 =340282366920938463463374607607431768211456
10 ^ 38 =100000000000000000000000000000000000000000000
实际上是:3.4028234664×10 ^ 38