$ python --version
Python 2.7.15
$ type test.py
import random
while True:
a = random.uniform(0, 1)
b = a ** 2
c = a * a
if b != c:
print "a = {}".format(a)
print "a ** 2 = {}".format(b)
print "a * a = {}".format(c)
break
$ python test.py
a = 0.145376687586
a ** 2 = 0.0211343812936
a * a = 0.0211343812936
I was only able to reproduce this on a Windows build of Python - to be precise: Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32
. On my Arch Linux box installation of Python (Python 2.7.15 (default, May 1 2018, 20:16:04) [GCC 7.3.1 20180406] on linux2
) the loop does not seem to terminate indicating that the a**2 = a * a
invariant holds there.
What is going on here? I know that IEEE floats come with a plethora of misconceptions and idiosyncrasies (this, for example, does not answer my question), but I fail to see what part of the specification or what kind of implementation of **
could possibly allow for this.
To address the duplicate flagging: This is most likely not directly an IEEE floating point math problem and more of a implementation issue of the **
operator. Therefore, this is not a duplicate of questions which are only asking about floating point issues such as precision or associativity.
As of 2020, there is no such way to represent infinity as an integer in any programming language so far. But in python, as it is a dynamic language, float values can be used to represent an infinite integer. One can use float('inf') as an integer to represent it as infinity.
It's a problem caused when the internal representation of floating-point numbers, which uses a fixed number of binary digits to represent a decimal number. It is difficult to represent some decimal number in binary, so in many cases, it leads to small roundoff errors.
The floating-point calculations are inaccurate because mainly the rationals are approximating that cannot be represented finitely in base 2 and in general they are approximating numbers which may not be representable in finitely many digits in any base.
The float type in Python represents the floating point number. Float is used to represent real numbers and is written with a decimal point dividing the integer and fractional parts. For example, 97.98, 32.3+e18, -32.54e100 all are floating point numbers.
Python relies on the underlying platform for its floating-point arithmetic. I hypothesize that Python’s **
operator uses a pow
implementation (as used in C) (confirmed by user2357112 referring to Python 2.7.15 source code).
Generally, pow
is implemented by using (approximations of) logarithms and exponentials, in part. This is necessary since pow
supports non-integer arguments. (Of course, this general implementation does not preclude specializations for subsets of its domain.)
Microsoft’s pow
implementation is notoriously not good. Hence, for pow(a, 2)
, it may be returning a result not equal to a*a
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With