将 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 这是精确解。