0

When checking if a floor is an int, the recommend method would be is_integer:

However, I get a weird behaviour with the results of the log function:

print(log(9,3));                        #2.0
print((log(9,3)).is_integer());         #True

print((log(243,3)));                    #5.0
print((log(243,3)).is_integer());       #False

Furthermore:

print((int) (log(9,3)));    #2
print((int) (log(243,3)));  #4

Is this normal?

felipsmartins
  • 13,269
  • 4
  • 48
  • 56
user3452075
  • 411
  • 1
  • 6
  • 17

2 Answers2

4

log(243,3) simply doesn't give you exactly 5:

>>> '%.60f' % log(243,3)
'4.999999999999999111821580299874767661094665527343750000000000'

As the docs say, log(x, base) is "calculated as log(x)/log(base)". And neither log(243) nor log(3) can be represented exactly, and you get rounding errors. Sometimes you're lucky, sometimes you're not. Don't count on it.

Stefan Pochmann
  • 27,593
  • 8
  • 44
  • 107
3

When you want to compare float numbers, use math.isclose().

When you want to convert a float number that is close to an integer, use round().

Float numbers are too subject to error for "conventional" methods to be used. Their precision (and the precision of functions like log) is too limited, unfortunately. What looks like a 5 may not be an exact 5.

And yes: it is normal. This is not a problem with Python, but with every language I'm aware of (they all use the same underlying representation). Python offers some ways to work around float problems: decimal and fractions. Both have their own drawbacks, but sometimes they help. For example, with fractions, you can represent 1/3 without loss of precision. Similarly, with decimal, you can represent 0.1 exactly. However, you'll still have problems with log, sqrt, irrational numbers, numbers that require many digits to be represented and so on.

Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69