$ 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.