classification
Title: Wrong calculation
Type: performance Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: an0n.r00t32, steven.daprano, tim.peters
Priority: normal Keywords:

Created on 2018-04-27 05:33 by an0n.r00t32, last changed 2018-04-27 06:45 by steven.daprano. This issue is now closed.

Messages (5)
msg315826 - (view) Author: (an0n.r00t32) Date: 2018-04-27 05:33
I found that python calculate this wrong. Other calculators gave me 9997809307 not 9997809507 (python), even python3 calculated it correctly. Here is the computation expression which Python 2.7 calculated wrong.

https://pastebin.com/uKx1FYx3
msg315827 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2018-04-27 05:44
Please find a minimal example that illustrates the problem you think you've found, and paste the plain text _into_ the bug report.

In the meantime, I'm closing this as "not a bug".  The division operator applied to integers in Python 2 defaults doing truncating integer division, and in Python 3 defaults to doing floating point division instead.  So this example all by itself is enough to show a difference:

Under Python 2.7.11:

>>> 1/8
0

Under Python 3.6.5:

>>> 1/8
0.125

Both are expected.

In exactly the same way, the subexpression "2*1*10/100*10*10+100/10" in the code you pasted returns the integer 10 under Python 2 but the floating point value 30.0 under Python 3.
msg315828 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2018-04-27 06:40
I agree with Tim that this is likely to be the difference between Python 2 truncating division and Python 3 division.

For the record, I get the following results:

9997809507L Python 2.7
9997809307.0 Python 3.5
9997809307 R
9997809307 Javascript (Rhino)
9997809307 OpenXion

I tried it in Ruby 1.8 as well, and sometimes got a syntax error and sometimes 9999599931. I have no idea why the odd results.

I'm not mad enough to type the whole thing into my calculator, but I am mad enough to simplify it by hand, and I get:

-590072-2/10*100-200112-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100+9998599835

Even Ruby gets the right answer (9997809507) for that :-)

In Python 2, 2/10 returns 0 unless you have run `from __future__ import division`, so the -2/10*100 terms all go to zero, and we get:

-590072-2/10*100-200112-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100-18-2/10*100+9998599835

which evaluates to 9997809307.0 just as Python 2.7 says.

So Tim was right, this is entirely due to the difference between / as truncating division in Python 2 and true division in Python 3.

Oh, and one last thing... in Python 2, you can get the expected result by either using the future import above, or by adding a decimal point to the numbers being divided, turning them into floats and forcing Python to use floating point true division.
msg315829 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2018-04-27 06:42
> Even Ruby gets the right answer (9997809507) for that :-)

Oops, I forgot to say... Ruby 1.8 also does truncating division like Python 2.
msg315830 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2018-04-27 06:45
Ah sheesh I copied and pasted the wrong bits. After the division terms go to zero, you get

-590072-200112-18-18-18-18-18-18-18-18+9998599835

which goes to 9997809507 as calculated by Ruby and Python 2, and I promise that's the end of me replying to myself :-)
History
Date User Action Args
2018-04-27 06:45:28steven.dapranosetmessages: + msg315830
2018-04-27 06:42:37steven.dapranosetmessages: + msg315829
2018-04-27 06:40:31steven.dapranosetnosy: + steven.daprano
messages: + msg315828
2018-04-27 05:44:29tim.peterssetstatus: open -> closed

nosy: + tim.peters
messages: + msg315827

resolution: not a bug
stage: resolved
2018-04-27 05:33:07an0n.r00t32create