以编程方式创建带符号 32 位浮点数的最大值 (Python3)
Programmatic way to create Decimal of max of signed 32-bit float (Python3)
问题陈述和背景
我正在编写一个函数,它被赋予包含单个浮点值的字符串,例如“3.14159”。
我想做的是评估这个浮点数是否在带符号的 32 位浮点数(也是 64 位,但现在让我们忘记它)的边界内。
由于浮点精度问题,我想使用Decimal
对象进行比较。
我要问的是:
如何创建一个 Decimal
其中包含最大有符号 32 位浮点数的值?
这将用于比较。
我尝试过的:
浏览这篇维基百科文章后: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
(wiki)
我觉得我好像错过了什么......也许今天已经太晚了?
读数:
实际上是:3.4028234664 × 10^38
尝试查找以下数字:
2^128 =
340282366920938463463374607431768211456
10^38 =
100000000000000000000000000000000000000
… the boundaries of the a signed 32-bit float…
float
中可表示的数的范围是-∞到+∞,所以所有的有限数都在这个范围内。但我想你想考虑 float
类型的有限范围,而不是整个范围。
_23bit_max_bin = '1' * 23 # '11111111111111111111111'
_23bit_max_dec = int(_23bit_max_bin, 2) # 8388607
这为您提供了 float
编码的有效数字字段的最大值,解释为二进制整数。那不是所表示的尾数的最大值。
假设指数字段既不全为零也不全为1,则表示的有效位数是二进制为“1”后跟“.”的数。其次是有效位域的位。所以最大有效数是 1.111111111111111111111112 = 21−2−23.
exponent_bin = '1' * 8 # '11111111'
这为您提供了指数字段的最大值。但是,指数字段的最大值用于编码无穷大和 NaN,而不是有限数。用于有限数的指数字段的最大值是 111111102 (25410)。此外,表示的指数是指数字段(解释为二进制整数)的值减去 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的最大指数次方,所以是(21−2−23) • 2127 = 2128 − 2104 = 340282346638528859811704183484516925440。我们称这个号码为 M.
但是,在判断一个十进制数是否在范围内时,你应该考虑是否要考虑:
- 数字在-M至+M之间,含,或
- 该数字在转换为
float
后正常舍入将产生 −M 到 +M[=88 之间的值的范围内=],包括在内(即,它不会四舍五入为无穷大)。
在后一种情况下,在舍入到最近的模式中,您想要的限制是 2128 − 2104 + 2103 = 2128 − 2103 = 340282356779733661637539395458142568448,独占。那个“半步”,2103,朝向下一个可表示的数字,如果指数范围继续前进,就是舍入到最近的方法在向下舍入和向上舍入之间变化的地方.如果恰好在该点上出现平局,则它四舍五入到具有偶数有效位的数字,这将是向上的。所以你想排除它,因此间隔是排他的而不是包含的。
一般情况下,如果精度为p(有效位有p−1位),指数位有w位,指数偏差为2w−1−1,最大指数相同,最大可表示的有限值是 (2−21−p) • 22 w−1−1 = (1−2−p) • 2 2w−1.
问题陈述和背景
我正在编写一个函数,它被赋予包含单个浮点值的字符串,例如“3.14159”。
我想做的是评估这个浮点数是否在带符号的 32 位浮点数(也是 64 位,但现在让我们忘记它)的边界内。
由于浮点精度问题,我想使用Decimal
对象进行比较。
我要问的是:
如何创建一个 Decimal
其中包含最大有符号 32 位浮点数的值?
这将用于比较。
我尝试过的:
浏览这篇维基百科文章后: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
(wiki)
我觉得我好像错过了什么......也许今天已经太晚了?
读数:
实际上是:3.4028234664 × 10^38
尝试查找以下数字:
2^128 = 340282366920938463463374607431768211456
10^38 = 100000000000000000000000000000000000000
… the boundaries of the a signed 32-bit float…
float
中可表示的数的范围是-∞到+∞,所以所有的有限数都在这个范围内。但我想你想考虑 float
类型的有限范围,而不是整个范围。
_23bit_max_bin = '1' * 23 # '11111111111111111111111'
_23bit_max_dec = int(_23bit_max_bin, 2) # 8388607
这为您提供了 float
编码的有效数字字段的最大值,解释为二进制整数。那不是所表示的尾数的最大值。
假设指数字段既不全为零也不全为1,则表示的有效位数是二进制为“1”后跟“.”的数。其次是有效位域的位。所以最大有效数是 1.111111111111111111111112 = 21−2−23.
exponent_bin = '1' * 8 # '11111111'
这为您提供了指数字段的最大值。但是,指数字段的最大值用于编码无穷大和 NaN,而不是有限数。用于有限数的指数字段的最大值是 111111102 (25410)。此外,表示的指数是指数字段(解释为二进制整数)的值减去 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的最大指数次方,所以是(21−2−23) • 2127 = 2128 − 2104 = 340282346638528859811704183484516925440。我们称这个号码为 M.
但是,在判断一个十进制数是否在范围内时,你应该考虑是否要考虑:
- 数字在-M至+M之间,含,或
- 该数字在转换为
float
后正常舍入将产生 −M 到 +M[=88 之间的值的范围内=],包括在内(即,它不会四舍五入为无穷大)。
在后一种情况下,在舍入到最近的模式中,您想要的限制是 2128 − 2104 + 2103 = 2128 − 2103 = 340282356779733661637539395458142568448,独占。那个“半步”,2103,朝向下一个可表示的数字,如果指数范围继续前进,就是舍入到最近的方法在向下舍入和向上舍入之间变化的地方.如果恰好在该点上出现平局,则它四舍五入到具有偶数有效位的数字,这将是向上的。所以你想排除它,因此间隔是排他的而不是包含的。
一般情况下,如果精度为p(有效位有p−1位),指数位有w位,指数偏差为2w−1−1,最大指数相同,最大可表示的有限值是 (2−21−p) • 22 w−1−1 = (1−2−p) • 2 2w−1.