将 41 位浮点数转换为十六进制
converting 41digit float to hexadecimal
我正在玩一些 RSA 密码计算,其中之一正在计算
very-large-number**(1/3)
其中非常大的数字是 100 位。我需要最终结果为十六进制才能得到最终结果。
我尝试了通常的 float.hex() hex(int(n)) 甚至这里的一些散文解决方案
但我得到的结果要么是科学格式 (xx.xxxx+40),要么输出的后半部分全是 0(我知道这是不正确的)
示例:
>>> n=14887716705766614226302331656748546195328906880296894322596715261404953788693951344841626882745910926946567107240171862117
>>> ct=n**(1/3)
>>> ct.hex()
'0x1.212d39ed89671p+134'
>>> print(ct)
2.4600430019674926e+40
>>> print(ct.hex())
0x1.212d39ed89671p+134
hex(int(ct))
'0x484b4e7b6259c400000000000000000000'
>>> int(ct)
24600430019674926067273894051435979472896
那么如何得到十六进制值呢? hex(int(ct)) 的第一部分)0x484b4e7b6259c)是正确的,所以这似乎表明精度错误。
我也尝试过使用 numpy:
>>> import numpy as np
>>> x=np.longdouble(14887716705766614226302331656748546195328906880296894322596715261404953788693951344841626882745910926946567107240171862117)
>>> float_formatter='{e:f}'.format
>>> np.set_printoptions(formatter={'float_kind':float_formatter},precision=128)
>>> ct=np.cbrt(x)
>>> np.cbrt(x)
2.4600430019675053399e+40
>>> print(ct)
2.4600430019675053399e+40
编辑:
计算的实际结果应该是: 24600430019675053398291607284547696341373 在十六进制之前应该变成 0x484B4E7B625A2D53644D2D64644F72317D 作为十六进制
快速检查现有的 online converter,您的两个输出实际上是相同的数字
'0x484b4e7b6259c400000000000000000000'
等于
24600430019674926067273894051435979472896
问题是,虽然 Python 整数是多精度数字,但浮点数只有 64 位 IEEE 754 浮点数,精度限制为 15 或 16 位十进制数字。
这意味着浮点运算n ** (1/3)
只会给出一个近似值。
但是您可以使用牛顿法找到更准确的方程 x**3 = n:
的解
def sqr3(n):
s0 = int(n ** (1/3))
s1 = 0
while True:
s1 = s0 + (n - s0 **3) // 2 // s0 // s0
if s1 ** 3 == n:
break
if (s0 - 1 <= s1 <= s0 + 1):
# should search further whether s0 or s1 (or maybe next iteration)
# would be the best one...
break
s0 = s1
return s1
它给出 sqr3(n)
: 24600430019675053398291607284547696341373
这是精确解。
我正在玩一些 RSA 密码计算,其中之一正在计算
very-large-number**(1/3)
其中非常大的数字是 100 位。我需要最终结果为十六进制才能得到最终结果。
我尝试了通常的 float.hex() hex(int(n)) 甚至这里的一些散文解决方案
但我得到的结果要么是科学格式 (xx.xxxx+40),要么输出的后半部分全是 0(我知道这是不正确的)
示例:
>>> n=14887716705766614226302331656748546195328906880296894322596715261404953788693951344841626882745910926946567107240171862117
>>> ct=n**(1/3)
>>> ct.hex()
'0x1.212d39ed89671p+134'
>>> print(ct)
2.4600430019674926e+40
>>> print(ct.hex())
0x1.212d39ed89671p+134
hex(int(ct))
'0x484b4e7b6259c400000000000000000000'
>>> int(ct)
24600430019674926067273894051435979472896
那么如何得到十六进制值呢? hex(int(ct)) 的第一部分)0x484b4e7b6259c)是正确的,所以这似乎表明精度错误。
我也尝试过使用 numpy:
>>> import numpy as np
>>> x=np.longdouble(14887716705766614226302331656748546195328906880296894322596715261404953788693951344841626882745910926946567107240171862117)
>>> float_formatter='{e:f}'.format
>>> np.set_printoptions(formatter={'float_kind':float_formatter},precision=128)
>>> ct=np.cbrt(x)
>>> np.cbrt(x)
2.4600430019675053399e+40
>>> print(ct)
2.4600430019675053399e+40
编辑: 计算的实际结果应该是: 24600430019675053398291607284547696341373 在十六进制之前应该变成 0x484B4E7B625A2D53644D2D64644F72317D 作为十六进制
快速检查现有的 online converter,您的两个输出实际上是相同的数字
'0x484b4e7b6259c400000000000000000000'
等于
24600430019674926067273894051435979472896
问题是,虽然 Python 整数是多精度数字,但浮点数只有 64 位 IEEE 754 浮点数,精度限制为 15 或 16 位十进制数字。
这意味着浮点运算n ** (1/3)
只会给出一个近似值。
但是您可以使用牛顿法找到更准确的方程 x**3 = n:
def sqr3(n):
s0 = int(n ** (1/3))
s1 = 0
while True:
s1 = s0 + (n - s0 **3) // 2 // s0 // s0
if s1 ** 3 == n:
break
if (s0 - 1 <= s1 <= s0 + 1):
# should search further whether s0 or s1 (or maybe next iteration)
# would be the best one...
break
s0 = s1
return s1
它给出 sqr3(n)
: 24600430019675053398291607284547696341373
这是精确解。