Converting number in scientific notation to int
Asked Answered
W

4

44

Could someone explain why I can not use int() to convert an integer number represented in string-scientific notation into a python int?

For example this does not work:

print int('1e1')

But this does:

print int(float('1e1'))

print int(1e1)  # Works

Why does int not recognise the string as an integer? Surely its as simple as checking the sign of the exponent?

Wanigan answered 30/9, 2015 at 8:31 Comment(5)
For the same reason that int() doesn't work on, say, '1.0': it is intended for integers.Thunderous
What do you think would happen with int('hello world')? It fails for the exact same reason that int('1e1') does - int() parses integer strings, like it says on the tin.Thunderous
1e1 is an integer! It is the number 10. I just wanted to know why you have to interpret a string of it as a float in order to realise it is an integer.Wanigan
No it isn't. Put 1e1 into an interpreter and watch it return 10.0. If that doesn't say "float" to you, try type(1e1) and watch it return <class 'float'>. Of course, the fact that only float(), and not int(), could parse the string '1e1' is a good indication, as well.Thunderous
The question is: why, when Python treats ints as floats (numeric hierarchy)… does it not treat a clear int as an int. How do you do an int that's 1e100? Try it. In Python3. Fun. 1e1000? Right out.Install
T
26

Behind the scenes a scientific number notation is always represented as a float internally. The reason is the varying number range as an integer only maps to a fixed value range, let's say 2^32 values. The scientific representation is similar to the floating representation with significant and exponent. Further details you can lookup in https://en.wikipedia.org/wiki/Floating_point.

You cannot cast a scientific number representation as string to integer directly.

print int(1e1)  # Works

Works because 1e1 as a number is already a float.

>>> type(1e1)
<type 'float'>

Back to your question: We want to get an integer from float or scientific string. Details: https://docs.python.org/2/reference/lexical_analysis.html#integers

>>> int("13.37")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '13.37'

For float or scientific representations you have to use the intermediate step over float.

Terrific answered 30/9, 2015 at 8:33 Comment(8)
It does? Personally, I don't think it clarifies the difference between numbers represented as strings and numbers stored as numbers, or the valid arguments for int().Thunderous
@Thunderous It similar to int('13.37').Terrific
I know that (in fact, I gave a similar example in a comment), but this answer doesn't seem to actually explain anything. To be fair, I'm not sure there's anything useful to say when the question is basically "why can't I send a string that doesn't represent an integer to a function that parses strings that represent integers?".Thunderous
Positive exponent means its an integer, it would just be nice if python could sort this out automatically.Wanigan
@Wanigan Sure but then python has to check the number ranges and so on. I think the gained complexity is not related to this simple case: It will be a float.Terrific
@Thunderous Sure. This would be enough for a normal user. My answer tries to figure out what and why the machine behaves scientific notations to be floating numbers. The answer is not for those who do not want to look beyond the bigger picture. In this context I don't want to just explain why you cannot feed int with scientific representation.Terrific
It's a Python question and you answer with 32 bit nonsense. Python can easily do 1e100 as an int ( but have fun entering it… because int(1e100) is obviously obvious.Install
@JürgenA.Erhard >>> type(int(1e100)) <type 'long'> docs.python.org/2/reference/lexical_analysis.html#integersTerrific
N
2

Very Simple Solution

print(int(float(1e1)))

Steps:- 1- First you convert Scientific value to float. 2- Convert that float value to int . 3- Great you are able to get finally int data type.

Enjoy.

Nineteen answered 21/11, 2019 at 12:44 Comment(2)
You don't need the float, and this is the same answer as accepted. isinstance(1e1, float) == True. Just int(1e1) is enough, which makes this answer a duplicate.Gurge
The clou of this solution is, that int(float("1e1")) works, while int("1e1") won't. Maybe the description should be a bit more clear. Still +1.Berthold
K
0

Because in Python (at least in 2.x since I do not use Python 3.x), int() behaves differently on strings and numeric values. If you input a string, then python will try to parse it to base 10 int

int ("077")
>> 77

But if you input a valid numeric value, then python will interpret it according to its base and type and convert it to base 10 int. then python will first interperet 077 as base 8 and convert it to base 10 then int() will jsut display it.

int (077)  # Leading 0 defines a base 8 number.
>> 63
077 
>> 63

So, int('1e1') will try to parse 1e1 as a base 10 string and will throw ValueError. But 1e1 is a numeric value (mathematical expression):

1e1
>> 10.0

So int will handle it as a numeric value and handle it as though, converting it to float(10.0) and then parse it to int. So Python will first interpret 1e1 since it was a numric value and evaluate 10.0 and int() will convert it to integer.

So calling int() with a string value, you must be sure that string is a valid base 10 integer value.

Kaye answered 30/9, 2015 at 8:44 Comment(6)
The phenomenon in the question (can't parse a non-integer string with int()) doesn't really have anything to do with Python 2 vs 3...Thunderous
I did not use Python 3 so I am not sure if this behaviour is changed or not. Fixed, thanks.Kaye
Why the downvote? Please explain so I can explain it or fix it.Kaye
int(077) is wrong because the behavior is not int's.Install
The main critique I see is that 1e1 is considered float when it's actually a numerically valid int. Python (and its ancestors) is actually quite dumb.Install
@JürgenA.Erhard do not remember what I was thinking while writing this answer. Fixed the issues... ThanksKaye
P
0

int(float(1e+001)) will work.

Whereas like what others had mention 1e1 is already a float.

Paisano answered 3/4, 2022 at 7:54 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Aureus

© 2022 - 2024 — McMap. All rights reserved.