[Dan, this isn't "aimed" at you personally, it's just a follow-up on the general point I am (and I think you are also) making]

On 11/02/17 02:17, Dan Sommers wrote:
At least it works both ways:

Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
s = "33333333333333333333333333333333333333333333333333333333333333333"
f = float(s)
i = int(s)

Yes, but Peter said "accept the number as a float, and then complain if int(num) != num.", so he meant use "i = int(f)" (i.e., convert the float to an int, not the original string).

Anyway, that's just as bad, but in a different way ;) Using your example:

Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> s = "33333333333333333333333333333333333333333333333333333333333333333"
>>> f = float(s)
>>> f
3.3333333333333333e+64
>>> i = int(f)
>>> i
33333333333333333069679542094544616940918707231410151788522766336
>>> i == f
True
>>>

That's poor if "i" ends up being the value actually used later when the input is processed - it's NOT the value the user entered!

I imagine that this particular use-case is not trying to teach the OP about float/int issues, but about how to parse numerical strings from user-input (so these extreme cases are not expected to be part of the input range). I might be wrong, though.

However, these sorts of issues are a very important consideration for people writing real-world code where the input might be coming from an external source such as a database or output from a language which uses fixed-point or some other precise representation of decimals (e.g., COBOL).

Whenever you convert something that may not be an integer in the appropriate range to a float (using IEEE 754, at least) you must be aware that you may lose precision. The answer in this case is to do something similar to what Peter suggested, but to use Python's 'decimal' type as the intermediate representation rather than the float() type:

Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from decimal import Decimal as dec
>>> s = "0.99999999999999995"
>>> d = dec(s)
>>> i = int(d)
>>> d
Decimal('0.99999999999999995')
>>> i
0
>>> i == d
False
>>> s = "33333333333333333333333333333333333333333333333333333333333333333"
>>> d = dec(s)
>>> i = int(d)
>>> d
Decimal('33333333333333333333333333333333333333333333333333333333333333333')
>>> i
33333333333333333333333333333333333333333333333333333333333333333
>>> i == d
True


No surprises there ;)

E.
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to