Floating point calculation problem
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sat Feb 2 06:45:38 EST 2013
Schizoid Man wrote:
> "Chris Angelico" <rosuav at gmail.com> wrote in message
> news:mailman.1289.1359801291.2939.python-list at python.org...
>> On Sat, Feb 2, 2013 at 9:27 PM, Schizoid Man <schiz_man at 21stcentury.com>
>> wrote:
>>> The quantity s is input with the following line: s = input("Enter s:
>>> ")
>>>
>>> To get rid of the compile error, I can cast this as a float: s =
>>> float(input("Enter s: "))
>>>
>>> However, then the result returned by the method is wrong. Why does this
>>> error occur in version 3.3.0 but not in 2.7.3? Why is the result
>>> incorrect
>>> when s is cast as a float (the casting is not required in 2.7.3)? How is
>>> Python dynamically typed if I need to cast (in version 3.3.0 at least)
>>> to get rid of the compile error?
>>
>> Did you use input() or raw_input() in 2.7.3? If the former, you were
>> actually doing this:
>>
>> s = eval(input("Enter s: "))
>>
>> That's extremely dangerous and inadvisable, so it's better to go with
>> 3.3 or the raw_input function.
>
> Thanks for the reply. You're right - even in 2.7.3 if I toggle between
> float(input(x)) and input(x), the result of the calculation changes.
Highly unlikely. I'd say impossible, unless you type a different value for x
of course. By the time the input() function returns, the result is already
a float. Wrapping it in float() again cannot possibly change the value. If
you have found a value that does change, please tell us what it is.
The only examples I can think of that will behave that way involve NANs and
INFs. If you don't know what they are, don't worry about it, and forget I
mentioned them. For regular floating point values, I can't think of any
possible way that float(input(x)) and input(x) could give different
results.
> What does the float cast do exactly?
float(x) converts x into a float.
- if x is already a float, it leaves it unchanged;
- if x is a string, it converts it to the nearest possible float;
- if x is some other numeric value (e.g. int, Decimal or Fraction,
but not complex) it converts it to the nearest possible float.
>> Passing it through float() is, most likely, the right way to do this.
>> But what do you mean by "the result... is wrong"? That's the bit to
>> look into.
>
> Scratch that, I'm not sure which result is right now, so need to look at
> the full calculations in details. What would be the difference between
> raw_input() and float(input())?
In Python 2.x, raw_input returns a string. To turn it into a float, you need
to use float(raw_input()).
float(input()) is a waste of time. The dangerous part happens in the call to
input(): a malicious user could type a Python command, and run arbitrary
code; or they could type something like "10**100**100" and lock up your
computer. Calling float *after* the call to input doesn't do anything.
In Python 3.x, raw_input is gone, but float(input()) is safe -- it is
exactly equivalent to float(raw_input()) in Python 2.x.
One other difference between Python 2.7 and 3.3 is that they sometimes
display floats slightly differently. Sometimes 3.3 will show more decimal
places:
[steve at ando ~]$ python2.7 -c "x = 1.0/33; print (x+x+x)"
0.0909090909091
[steve at ando ~]$ python3.3 -c "x = 1.0/33; print (x+x+x)"
0.09090909090909091
but you can be sure that they are the same value, it is just a difference in
the default display of floats:
[steve at ando ~]$ python2.7 -c "x = 1.0/33; print (x+x+x).hex()"
0x1.745d1745d1746p-4
[steve at ando ~]$ python3.3 -c "x = 1.0/33; print((x+x+x).hex())"
0x1.745d1745d1746p-4
--
Steven
More information about the Python-list
mailing list