Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Floating point calculation problem

Reply
Thread Tools

Re: Floating point calculation problem

 
 
Chris Angelico
Guest
Posts: n/a
 
      02-02-2013
On Sat, Feb 2, 2013 at 9:27 PM, Schizoid Man <(E-Mail Removed)> 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.

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.

ChrisA
 
Reply With Quote
 
 
 
 
Schizoid Man
Guest
Posts: n/a
 
      02-02-2013
"Chris Angelico" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On Sat, Feb 2, 2013 at 9:27 PM, Schizoid Man <(E-Mail Removed)>
> 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. What
does the float cast do exactly?

> 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())?

Thanks again.

 
Reply With Quote
 
 
 
 
Chris Angelico
Guest
Posts: n/a
 
      02-02-2013
On Sat, Feb 2, 2013 at 10:14 PM, Schizoid Man <(E-Mail Removed)> wrote:
> 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())?
>
> Thanks again.


Depends on what you type in.

raw_input() takes a line from the keyboard (handwave) and returns it
as a string.

input() in 2.X takes a line from the keyboard and evaluates it as a
Python expression.

float() takes a string, float, int, etc, and returns the
nearest-equivalent floating point value.

What's the input you're giving to it?

ChrisA
 
Reply With Quote
 
Schizoid Man
Guest
Posts: n/a
 
      02-02-2013
> raw_input() takes a line from the keyboard (handwave) and returns it
> as a string.
>
> input() in 2.X takes a line from the keyboard and evaluates it as a
> Python expression.
>
> float() takes a string, float, int, etc, and returns the
> nearest-equivalent floating point value.
>
> What's the input you're giving to it?


Something simple like 3.0.

PS - I'm new to Python, hence the newbie questions.
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      02-02-2013
On Sat, Feb 2, 2013 at 10:34 PM, Schizoid Man <(E-Mail Removed)> wrote:
>> raw_input() takes a line from the keyboard (handwave) and returns it
>> as a string.
>>
>> input() in 2.X takes a line from the keyboard and evaluates it as a
>> Python expression.
>>
>> float() takes a string, float, int, etc, and returns the
>> nearest-equivalent floating point value.
>>
>> What's the input you're giving to it?

>
>
> Something simple like 3.0.


If your input has no decimal point in it, eval (or input) will return
an integer, not a float. Other than that, I can't see any obvious
reason for there to be a difference. Can you put together a simple
script that demonstrates the problem and post it, along with the exact
input that you're giving it, and the different outputs?

Chris Angelico
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      02-02-2013
Schizoid Man wrote:

> "Chris Angelico" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> On Sat, Feb 2, 2013 at 9:27 PM, Schizoid Man <(E-Mail Removed)>
>> 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@ando ~]$ python2.7 -c "x = 1.0/33; print (x+x+x)"
0.0909090909091
[steve@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@ando ~]$ python2.7 -c "x = 1.0/33; print (x+x+x).hex()"
0x1.745d1745d1746p-4
[steve@ando ~]$ python3.3 -c "x = 1.0/33; print((x+x+x).hex())"
0x1.745d1745d1746p-4



--
Steven

 
Reply With Quote
 
Schizoid Man
Guest
Posts: n/a
 
      02-02-2013
> 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.
>


No, the calculation returns in neither NaN or Inf at any point.

> 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.
>
>
> 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:


Thanks for that, I'll post the problematic code here shortly.

 
Reply With Quote
 
Schizoid Man
Guest
Posts: n/a
 
      02-02-2013
> If your input has no decimal point in it, eval (or input) will return
> an integer, not a float. Other than that, I can't see any obvious
> reason for there to be a difference. Can you put together a simple
> script that demonstrates the problem and post it, along with the exact
> input that you're giving it, and the different outputs?


Understood. I'm trying to learn Python by porting an ODE solver I wrote over
from C#, so what I'll do is break down the routine and append a small code
snippet highlighting the difference.

I know this is probably redundant but Python 2.7.3 is running on a Mac and
3.3.0 on a PC, so it's not exactly an apples-v-apples comparison.

 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      02-02-2013
On Sat, Feb 2, 2013 at 10:51 PM, Schizoid Man <(E-Mail Removed)> wrote:
>> If your input has no decimal point in it, eval (or input) will return
>> an integer, not a float. Other than that, I can't see any obvious
>> reason for there to be a difference. Can you put together a simple
>> script that demonstrates the problem and post it, along with the exact
>> input that you're giving it, and the different outputs?

>
>
> Understood. I'm trying to learn Python by porting an ODE solver I wrote over
> from C#, so what I'll do is break down the routine and append a small code
> snippet highlighting the difference.


Thanks, I think I can speak for all of us in expressing appreciation
for that effort! It makes the job so much easier.

> I know this is probably redundant but Python 2.7.3 is running on a Mac and
> 3.3.0 on a PC, so it's not exactly an apples-v-apples comparison.


Ah, there may well be something in that. Definitely post the code and
outputs; chances are someone'll spot the difference.

ChrisA
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      02-02-2013
Schizoid Man wrote:

> I know this is probably redundant but Python 2.7.3 is running on a Mac and
> 3.3.0 on a PC, so it's not exactly an apples-v-apples comparison.


It's not impossible that there is a slight difference in some of the
floating point functions. E.g. when you call math.log(s), one version might
be accurate to (say) 15 decimal places and the other to (say) 14 decimal
places, and that difference is magnified by subsequent calculations.



--
Steven

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Floating point calculation problem Steven D'Aprano Python 0 02-02-2013 12:05 PM
Re: Floating point calculation problem Chris Rebert Python 0 02-02-2013 10:47 AM
floating point calculation problem bei C++ 4 01-07-2010 09:01 PM
floating point calculation problem bei C++ 0 01-06-2010 02:43 AM
Floating point calculation problem Hyun chul Park Ruby 3 07-08-2008 09:15 AM



Advertisments