0

I'm solving some cryptographic problem,

I need the cube root of 4.157786362549383e+37, which gives me 3464341716380.1113

using

x = x ** (1. / 3)

I thought it was weird at first, so I did try:

x=1000
print(x)
x= pow(x,1/3)
print(x)

but got 9.99999998

I have even tried somewhere else. But i got the same result. Is there something wrong? How can I calculate the true cube root?

vsminkov
  • 10,912
  • 2
  • 38
  • 50
Gaston
  • 1,004
  • 1
  • 9
  • 23
  • 5
    This looks like a floating point issue ... http://stackoverflow.com/q/588004/748858 . You probably won't get any better without some library for working with symbolic manipulation (e.g. `sympy`) – mgilson Sep 12 '16 at 22:13
  • Look at http://stackoverflow.com/questions/14057835/more-decimal-places-needed-in-python, it won't be a true cube root but it may be closer. – Dan. K Sep 12 '16 at 22:14
  • Why do you think that 3464341716380.1113 is incorrect? – interjay Sep 12 '16 at 22:15

4 Answers4

1

Due to floating-point arithmetic, this is hard to represent.

Using decimal somewhat resolves it but is still problematic in certain numbers, and allows rounding only to integrals. Try using a decimal like so:

>>> (1000 ** (Decimal(1)/3)).to_integral_exact()
Decimal('10')
Bharel
  • 23,672
  • 5
  • 40
  • 80
0

This is normal when dealing with floating-point numbers on a computer. No decimal fraction can be represented precisely in binary, which deals in negative powers of 2, so you need to get used to getting very close approximations.

In this specific case, if you know your result is supposed to be an integer, simply use round().

kindall
  • 178,883
  • 35
  • 278
  • 309
0

Both answers are correct within the accuracy of the hardware's numerical representation. 1/3 is a repeating "decimal" in binary: 0.010101010101... It can't be represented precisely.

If you want a "true" cube root, you need to implement an algorithm that handles the round-off problems and corner cases you find useful. Given the representation problem, you could certainly cover integer cubes. However, noting even simple cases, such as cube_root(1.728) => 1.2, would be problematic: neither decimal number converts precisely to binary.

Prune
  • 76,765
  • 14
  • 60
  • 81
0

As discussed in other answers, this is due to the limited precision of floating point numbers. It's just not possible to exactly represent values, unless your math is done symbolically. If you are fine with limited precision but just need more precision than the built in datatypes give you, I suggest an arbitrary precision arithmetic library, such as this one.

Void Star
  • 2,401
  • 4
  • 32
  • 57