-1

According to these answers there is not difference between pow(a,b) and a**b. However, math.pow(a,b) returns a float value. Now, when running the following python code something strange happens:

>>>import math
>>>math.pow(19,13)%2537
2296.0
>>>pow(19,13)%2537
2299

These statements should give the same value but don't. Any clue as to why this happens?

Community
  • 1
  • 1
Squeek
  • 33
  • 7
  • 5
    http://stackoverflow.com/questions/10282674/difference-between-the-built-in-pow-and-math-pow-for-floats-in-python – Zhe He Oct 06 '16 at 16:10
  • 1
    `pow(19,13)%2537` gives me `2299L` in Python 2.7, not 2599. Where's the extra 300 from? – roganjosh Oct 06 '16 at 16:14
  • @roganjosh Sorry, my bad. It's a typo. – Squeek Oct 06 '16 at 16:18
  • @ZheHe 's link is quite informative but I don't think this question duplicates it. This question is partially about why the float value is significantly different than the integer value. – tdelaney Oct 06 '16 at 16:48

3 Answers3

1

As you say math.pow returns a float value and pow does not. Calling the modulo operator on a float will round it to an integer. Rounding floating point to integer will cause loss of precision.

>>> int(math.pow(19,13))
42052983462257056
>>> pow(19,13)
42052983462257059
Hans Then
  • 10,935
  • 3
  • 32
  • 51
0

math.pow() converts its arguments to float:

>>> import math
>>> import fractions
>>> math.pow(fractions.Fraction(3, 2), 2)
2.25

but the built-in pow does not:

>>> pow(fractions.Fraction(3, 2), 2)
Fraction(9, 4)

Also check: Difference between the built-in pow() and math.pow() for floats, in Python?

Community
  • 1
  • 1
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
0

The float type looses precision. They are represented by the nearest binary fraction and from the docs Floating Point Arithmetic: Issues and Limitations

Interestingly, there are many different decimal numbers that share the same nearest approximate binary fraction.

You can see the problem clearly with the result of math.pow(19,13) where multiple integers map to the same float.

>>> f = math.pow(19,13)
>>> float(int(f)) == float(int(f) - 1)
True
>>> float(int(f)) == float(int(f) - 2)
True
>>> float(int(f)) == float(int(f) - 3)
True
>>> float(int(f)) == float(int(f) - 4)
True
>>> float(int(f)) == float(int(f) - 5)
False

Since python can handle very large integers, try to stay away from floats!

tdelaney
  • 73,364
  • 6
  • 83
  • 116