This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Exponential notation should return an int if it can
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.9
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: Marco Sulla, eric.smith, steven.daprano, tim.peters, zach.ware
Priority: normal Keywords:

Created on 2020-02-28 21:36 by Marco Sulla, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (10)
msg362918 - (view) Author: Marco Sulla (Marco Sulla) * Date: 2020-02-28 21:36
(venv_3_9) marco@buzz:~/sources/python-frozendict$ python
Python 3.9.0a0 (heads/master-dirty:d8ca2354ed, Oct 30 2019, 20:25:01) 
[GCC 9.2.1 20190909] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 1E9
>>> type(a)
<class 'float'>

IMHO if the exponent is positive, and the  "base number" (1 in the example) is an integer, the result should be an integer.

Optionally, also if the "base number" has a number of decimal places <= the exponent, the result should be an integer. Example:

1.25E2 == 125

If the user wants a float, it can write

1.2500E2 == 125.0
msg362925 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-02-28 22:26
I strongly disagree. Even if I thought it was a good idea (I don't), we'd break too much code by making this change now.
msg362944 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2020-02-29 00:00
Agreed with Eric.
msg362952 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-02-29 00:44
I agree with both Eric and Zachary, but I just wanted to point out that in a Python interpreter with a keyhole optimizer, you can expect that expressions like `1*10**9` to be a constant:

# Python 3.5
py> from dis import dis
py> dis('1*10**9')
  1           0 LOAD_CONST               4 (1000000000)
              3 RETURN_VALUE

Marco, if you are worried about the performance cost of multiplying by a power of ten when creating constants, you shouldn't.
msg362999 - (view) Author: Marco Sulla (Marco Sulla) * Date: 2020-02-29 17:50
Sorry, but I can't figure out what code can break this change. Integers are implicitly converted to floats in operations with floats. How can this change break old code?

> if you are worried about the performance

No, I'm worried about the expectations of coders.
Personally, I expected that 1E2 returned a integer. And this is not true.
If I wanted a float, I'd wrote 1.0E2 . The fact the exponential notation returns always a float is really misleading, IMHO.
msg363002 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-02-29 18:30
> Integers are implicitly converted to floats in operations with floats. 
> How can this change break old code?

# Status quo
print(1e60 + 1)
=> prints 1e+60

# In the future:
=> prints 1000000000000000000000000000000000000000000000000000000000001

# Status quo
1e300*1e300
=> returns inf (a float)

# In the future
=> returns 1000000...000000 (600 zeroes, an int)

# Status quo:
1e300**10000
=> instantly raises overflow error

# In the future
=> locks up the machine until you run out of memory

etc.

> > if you are worried about the performance
> 
> No, I'm worried about the expectations of coders.

Oh that's good then, because exponentional notation like 1e10 has been 
well known to return a float in Python for over a quarter of a century, 
and in dozens or hundreds of other languages too. It is, as far as I can 
tell, universally true that coders can distinguish floats from ints (in 
languages that distinguish them) using a simple test:

- if it contains a ".", "e" or "E", it's a float
- otherwise its an int

I don't know of any languages where numbers containing a dot or an "E" 
are ints. Do you?

> If I wanted a float, I'd wrote 1.0E2 

But by your own feature request, this would return an int and your 
"feature" would bite you:

    if the "base number" has a number of decimal places <= the
    exponent, the result should be an integer.

You would need to write 1.000E2 for it to work. Luckily for you, we're 
rejecting this idea, before it can fool you into writing buggy code :-)
msg363008 - (view) Author: Marco Sulla (Marco Sulla) * Date: 2020-02-29 19:46
All the examples you mentioned seems to me to fix code, instead of breaking it.

About 1e300**10000, it's not a bug at all. No one can stop you to full your RAM in many other ways :-D

About conventions, it does not seems to me that Python cares about other languages very much, if it's more natural for normal people to expect a result instead of a consolidated one among devs. See `1 / 2 == 0.5`, for example.

> But by your own feature request, this would return an int and your 
"feature" would bite you

You're citing the *optional* extra to the original idea. We can agree it is not a good addition at all.

I continue to think that nE+m, where n and m are integers, should return an integer. If this can break old code, I'm the first to think it should not be implemented, but I don't see any problem (yet).
msg363009 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2020-02-29 19:48
Ya, this change will never be made - give up gracefully :-)

1e100 and 10**100 aren't just of different types, they have different mathematical _values_ now:

>>> 1e100 == 10**100
False
>>> int(1e100)
10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104

Of course this has visible consequences, like:

>>> 1e100 % 1000
104.0
>>> int(1e100) % 1000
104
>>> 10**100 % 1000
0
msg363010 - (view) Author: Marco Sulla (Marco Sulla) * Date: 2020-02-29 19:53
> >>> int(1e100)
> 10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104

.........
Oh my God... I'm just more convinced than before :-D

> Ya, this change will never be made - give up gracefully :-)

Well, even if it's Tim Peters himself that ask it to me :-) I can't.
msg363011 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2020-02-29 19:56
Then please take it to python-ideas?  The issue tracker isn't a right place for endless argument.  python-ideas is.  This is my last response here.
History
Date User Action Args
2022-04-11 14:59:27adminsetgithub: 83969
2020-02-29 19:56:52tim.peterssetmessages: + msg363011
2020-02-29 19:53:50Marco Sullasetmessages: + msg363010
2020-02-29 19:48:14tim.peterssetnosy: + tim.peters
messages: + msg363009
2020-02-29 19:46:04Marco Sullasetmessages: + msg363008
2020-02-29 18:30:24steven.dapranosetmessages: + msg363002
2020-02-29 17:50:09Marco Sullasetmessages: + msg362999
2020-02-29 00:44:26steven.dapranosetnosy: + steven.daprano
messages: + msg362952
2020-02-29 00:00:55zach.waresetstatus: open -> closed

nosy: + zach.ware
messages: + msg362944

resolution: rejected
stage: resolved
2020-02-28 22:26:15eric.smithsetnosy: + eric.smith
messages: + msg362925
2020-02-28 21:36:04Marco Sullacreate