Error in math.log() method

Hi! there,
(Python version 3.10.12)

the issue is log10(2)=x ( the values of x is 0.30102999566398114)
then 10^0.30102999566398114 should be equal to 2.0 but it is giving it as 1.9999999999999998
but for 10^0.3010299956639812 it is giving output as 2.0

print(math.log(2,10)) # 0.30102999566398114

print(math.pow(10,0.30102999566398114)) # 1.9999999999999998

mean while,
print(math.pow(10,0.3010299956639812)) # 2.0

This is simply how floating point numbers work. See https://0.30000000000000004.com/.

2 Likes

or 15. Floating-Point Arithmetic: Issues and Limitations — Python 3.12.5 documentation

this isn’t really a core-dev topic, for what it’s worth.

Maybe try Python 3.12.3

With it, in my computer, I get

math.log10(2)  #  = 0.3010299956639812
math.pow(10, math.log10(2))  #  = 2.0

Maybe they improved the implementation of math.log10 and/or math.pow.

This doesn’t mean that you won’t be able to find other examples where

math.pow(10, math.log10(x)) != x

It is hard to get exact values of transcendental functions. See Table-maker’s dilemma.


Note: It is a bit different issue (although related) the one that you are asking about from peculiarities of working with float, like a + (b + c) != (a + b) + c and things like that. While the latter is inescapable. It is a feature of float. The implementations of log10 and pow do have room for improvement in terms of precision (at some cost).

Note the difference between math.log(x, 10) and math.log10(x). As a rule, you should prefer base-specific logarithm functions when available for precisely this reason: they can be better at maintaining precision than the arbitrary base log function. They can also be faster and/or provide stronger guarantees (e.g. exact representation for some values, monotonicity) than their arbitrary-base counterpart, but that all depends on the C standard library implementation that Python links to.

Hardly so. I think that from very ancient times log10 is just a thin wrapper to libm’s log10.

But please note, that OP used log(2,10), not log10(2). So, you should be able to reproduce this (depends on your C stdlib implementation, not on CPython):

>>> import math
>>> x1 = math.log(2, 10); x1
0.30102999566398114
>>> x2 = math.log10(2); x2
0.3010299956639812
>>> r1 = pow(10, x1); r1
1.9999999999999998
>>> pow(10, x2)
2.0
>>> abs(r1 - 2)/math.ulp(2)  # tiny difference, < 1ULP
0.5
1 Like

I took at face value their first line.

They could find examples for math.pow(10, math.log10(x)) != x too.

A random example seems to be x = 0.24554385155642333.