I am playing around with some RSA crypto calculations and one of them is calculating
very-large-number**(1/3)
where very large number is 100 digits. I need the result as hexadecimal in the end to get the final result.
I have tried the usual float.hex() hex(int(n)) and even some of the prosed solutions from here Dealing with very large hex numbers in python
but the result I get is either in scientific format (xx.xxxx+40) or the last half of the outout is all 0 (which I know is not correct)
Example:
>>> 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
so how do I get the hex value out? the first part)0x484b4e7b6259c) from hex(int(ct)) is correct so this seem to indicate precision error.
I have also tried with 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
Edit: the actual result for the calculations should be: 24600430019675053398291607284547696341373 before hex which should turn into 0x484B4E7B625A2D53644D2D64644F72317D as hex
The problem is that while Python integers are multi-precision numbers, floats are only 64 bits IEEE 754 floating point numbers and have a precision limited to 15 or 16 decimal digits.
That means that the floating point n ** (1/3)
operation will only give an approximation. But you could use Newton method to find a more accurate solution of the equation 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
It gives for sqr3(n)
: 24600430019675053398291607284547696341373
which is the exact solution.
Doing a quick check with an existing online converter , your two outputs are in fact the same number
'0x484b4e7b6259c400000000000000000000'
equals
24600430019674926067273894051435979472896
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.