$ 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.
repr
to show more digits so we can see exactly what value it's failing on and how. – Coquilleformat
, use{.30}
or something. – Fustya ** 2
is not implemented asa * a
. – Stylitex ** n
should be equivalent to repeated multiplication ifn
happens to be an integer, much less implemented that way? – Fustya**2 == a*a
is just going to lead to pain. – Coquillea**2 == a*a
. Therefore, if it fails to hold in some implementation, there is a cause other than the nature of floating-point. And I have not suggested OP or anybody else rely on this identity. I have merely stated the cause of the failure is not due to the nature of floating-point arithmetic. – Freezedry