int vs. float
Erik
python at lucidity.plus.com
Sat Feb 11 17:33:53 EST 2017
[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.
More information about the Python-list
mailing list