将 41 位浮点数转换为十六进制

时间:2021-05-06 07:28:57

标签: python math rsa bigint

我正在玩一些 RSA 加密计算,其中之一正在计算

very-large-number**(1/3)

其中非常大的数字是 100 位数字。我需要最后的结果为十六进制才能得到最终结果。

我已经尝试了通常的 float.hex() hex(int(n)) 甚至一些从这里提出的解决方案 Dealing with very large hex numbers in python

但我得到的结果要么是科学格式(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 作为十六进制

2 个答案:

答案 0 :(得分:1)

问题在于,虽然 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 这是精确的解决方案。

答案 1 :(得分:0)

快速检查现有的online converter,您的两个输出实际上是相同的数字

'0x484b4e7b6259c400000000000000000000'

等于

24600430019674926067273894051435979472896