Floating point calculation problem
I have a program that performs some calculations that runs perfectly on Python 2.7.3. However, when I try to execute it on Python 3.3.0 I get the following error: numer = math.log(s) TypeError: a float is required 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? Thanks in advance. PS - I'm a Python newbie. -- http://mail.python.org/mailman/listinfo/python-list
Re: Floating point calculation problem
"Chris Angelico" wrote in message news:mailman.1289.1359801291.2939.python-l...@python.org... On Sat, Feb 2, 2013 at 9:27 PM, Schizoid Man 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. -- http://mail.python.org/mailman/listinfo/python-list
Re: Floating point calculation problem
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. -- http://mail.python.org/mailman/listinfo/python-list
Re: Floating point calculation problem
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. -- http://mail.python.org/mailman/listinfo/python-list
Re: Floating point calculation problem
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. -- http://mail.python.org/mailman/listinfo/python-list
Re: Floating point calculation problem
Ah, there may well be something in that. Definitely post the code and outputs; chances are someone'll spot the difference. Ok, I *think* I found the source of the difference: This is the base code that runs fine in v 3.3.0 (the output is correct): def Numer(s, k): return math.log(s / k) s = float(input("Enter s: ")) k = float(input("Enter k: ")) print("Result: ", Numer(s, k)) For the v2.7 version, the only difference is the input lines: s = input("Enter s: ") k = input("Enter k: ") So for values of s=60 and k=50, the first code returns 0.1823215567939546 (on the PC), whereas the second returns 0.0 (on the Mac). This this expression is evaluated in the numerator, it never returns a divide by zero error, and the result of 0 is treated as legitimate. However, if I cast the v2.7 inputs as float() then it does indeed return the right result. But what threw me was that no cast didn't result in a runtime error in 2.7, but did in 3.3. Also, if the cast is necessary, then now exactly does the dynamic typing work? Thanks. -- http://mail.python.org/mailman/listinfo/python-list
Re: Floating point calculation problem
"Schizoid Man" wrote in message news:kejcfi$s70$1...@dont-email.me... So for values of s=60 and k=50, the first code returns 0.1823215567939546 (on the PC), whereas the second returns 0.0 (on the Mac). This this expression is evaluated in the numerator, it never returns a divide by zero error, and the result of 0 is treated as legitimate. D'oh! That's the error right there. My inputs are 60 and 50, not 60.0 and 50.0. I am a dunderhead. Apologies for wasting your time. -- http://mail.python.org/mailman/listinfo/python-list
Confusing math problem
Hi there, I run the following code in Python 3.3.0 (on a Windows 7 machine) and Python 2.7.3 on a Mac and I get two different results: result1 = [] result2 = [] for a in range(2,101): for b in range(2,101): result1.append(math.pow(a,b)) result2.append(a**b) result1 = list(set(result1)) result2 = list(set(result2)) print (len(result1)) print (len(result2)) On the Windows box, I get 9183 for on both lines. However, on the Mac I get 9220 and 9183. Why this difference? Is there some sort of precision subtlety I'm missing between ** and math.pow()? Thank you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Confusing math problem
"Dave Angel" wrote in message On 02/21/2013 02:33 PM, Schizoid Man wrote: However, there is an important inaccuracy in math.pow, because it uses floats to do the work. If you have very large integers, that means some of them won't be correct. The following are some examples for 2.7.3 on Linux: a b math.pow(a,b) a**b 3 34 1.66771816997e+16 16677181699666569 3 35 5.0031545099e+16 50031545098999707 ... 5 23 1.19209289551e+16 11920928955078125 The built-in pow, on the other hand, seems to get identical answers for all these cases. So use pow() instead of math.pow() I see. I thought using the ** was shorthand for math.pow() and didn't think that one would be integer operations and the other floats. I'm performing some large integer arithmetic operations. I would normally do this my writing my own multiplication class and storing results as strings, but a friend suggested that I look at Python. I ran this one example and was quite surprised at the difference, since 9183 is the correct answer. One other test: diff = set(map(int, result1)).symmetric_difference(set(result2)) if diff: print diff print len(diff) shows me a diff set of 15656 members. One such member: 1355252715606880542509316001087427139282226562500L Notice how using floats truncated lots of the digits in the value? I'm running this test now, but the Mac's fan has kicked in (it's a slightly older machine) so might it let run through the night. I appreciate the help. -- DaveA -- http://mail.python.org/mailman/listinfo/python-list
Re: Confusing math problem
"Chris Angelico" wrote in First, are you aware that ** will return int (or sometimes long on 2.7.3), while math.pow() will return a float? That may tell you why you're seeing differences. That said, though, I wasn't able to replicate your result using 2.7.3 and 3.3.0 both on Windows - always 9183, indicating 618 of the powers are considered equal. But in theory, at least, what you're seeing is that 37 of them compare different in floating point on your Mac build. Something to consider: print(set(result1)-set(result2)) No, I was aware to be honest. I thought ** was just short hand for math.pow(). Since ** is the integer operation, I suppose ^ doesn't work as an exponent function in Python? I compared the difference and got a large blob of numbers. To make a proper comparison I'll need to compare the base and exponent for which the numbers are different rather than the numbers themselves. I'm following Dave's suggestion of determining the symmetric difference of the sets. Thanks for the help. -- http://mail.python.org/mailman/listinfo/python-list
Re: Confusing math problem
"Dave Angel" wrote One other test: diff = set(map(int, result1)).symmetric_difference(set(result2)) if diff: print diff print len(diff) shows me a diff set of 15656 members. One such member: 1355252715606880542509316001087427139282226562500L These are the results I got for len(diff): Windows machines: 15656, Mac: 15693. Someone mentioned something about processor algorithms on this thread and I do have a x86 Mac, so in terms of processors it's a like-for-like comparison. I have a follow-up question: are ** and pow() identical? -- http://mail.python.org/mailman/listinfo/python-list
Re: Confusing math problem
"Oscar Benjamin" wrote in Then you want operator.pow: import operator operator.pow(3, 2) 9 math.pow is basically the (double)pow(double, double) function from the underlying C library. operator.pow(a, b) is precisely the same as a**b. So how is operator.pow() different from just pow()? There's no need to use strings if you're working with integers in Python. The results with int (not float) will be exact and will not overflow since Python's ints have unlimited range (unless your machine runs out of memory but that only happens with *really* big integers). Yes, that's the idea. I haven't really used Python before, so was just kicking the tyres a bit and got some odd results. This forum has been great though. If you want to do computations with non-integers and high precision, take a look at the decimal and fractions modules. http://docs.python.org/2/library/decimal.html http://docs.python.org/2/library/fractions.html There is also a good third party library, sympy, for more complicated exact algebra: http://sympy.org/en/index.html Thanks a lot for the references, I'll definitely check them out. -- http://mail.python.org/mailman/listinfo/python-list
Beginner's assignment question
As in variable assignment, not homework assignment! :) I understand the first line but not the second of the following code: a, b = 0, 1 a, b = b, a + b In the first line a is assigned 0 and b is assigned 1 simultaneously. However what is the sequence of operation in the second statement? I;m confused due to the inter-dependence of the variables. -- http://mail.python.org/mailman/listinfo/python-list
Re: Beginner's assignment question
Lorenzo Gatti wrote: > On Mar 1, 3:39 pm, Schizoid Man <[EMAIL PROTECTED]> wrote: >> As in variable assignment, not homework assignment! :) >> >> I understand the first line but not the second of the following code: >> >> a, b = 0, 1 >> a, b = b, a + b >> >> In the first line a is assigned 0 and b is assigned 1 simultaneously. >> >> However what is the sequence of operation in the second statement? I;m >> confused due to the inter-dependence of the variables. > > The expressions of the right of the assignment operator are evaluated > before assigning any new values, to the destinations on the left side > of the assignment operator. > So substitutig the old values of a and b the second assignment means > > a, b = 0, 0 + 1 > > Simplifying the Python Reference Manual ("6.3 Assignment Statements") > a little : > > assignment_stmt ::= target_list "="+ expression_list > > An assignment statement evaluates the expression list (remember that > this can be a single expression or a comma-separated list, the latter > yielding a tuple) and assigns the single resulting object to each of > the target lists, from left to right. > > [...] > > WARNING: Although the definition of assignment implies that overlaps > between the left-hand side and the right-hand side are `safe' (for > example "a, b = b, a" swaps two variables), overlaps within the > collection of assigned-to variables are not safe! For instance, the > following program prints "[0, 2]": > > x = [0, 1] > i = 0 > i, x[i] = 1, 2 > print x > > Lorenzo Gatti Thank you for the explanation. I guess my question can be simplified as: First step: a, b = 0, 1 No problem here as a and b are assigned values. Second step: a, b = b, a + b Now my question is does b become a + b after a becomes 1 or while a stays at 0? As the assignment occurs simultaneously I suppose the answer is while a stays at 0. Thank you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Beginner's assignment question
Gabriel Genellina wrote: > En Sun, 02 Mar 2008 08:25:49 -0200, Schizoid Man <[EMAIL PROTECTED]> escribi�: > >> Lorenzo Gatti wrote: >>> On Mar 1, 3:39 pm, Schizoid Man <[EMAIL PROTECTED]> wrote: >>>> As in variable assignment, not homework assignment! :) >>>> >>>> I understand the first line but not the second of the following code: >>>> >>>> a, b = 0, 1 >>>> a, b = b, a + b >>>> >>>> In the first line a is assigned 0 and b is assigned 1 simultaneously. >>>> >>>> However what is the sequence of operation in the second statement? I;m >>>> confused due to the inter-dependence of the variables. >>> >>> The expressions of the right of the assignment operator are evaluated >>> before assigning any new values, to the destinations on the left side >>> of the assignment operator. >>> So substitutig the old values of a and b the second assignment means >>> >>> a, b = 0, 0 + 1 >>> >>> Simplifying the Python Reference Manual ("6.3 Assignment Statements") >>> a little : >>> >>> assignment_stmt ::= target_list "="+ expression_list >>> >>> An assignment statement evaluates the expression list (remember that >>> this can be a single expression or a comma-separated list, the latter >>> yielding a tuple) and assigns the single resulting object to each of >>> the target lists, from left to right. >>> >>> [...] >>> >>> WARNING: Although the definition of assignment implies that overlaps >>> between the left-hand side and the right-hand side are `safe' (for >>> example "a, b = b, a" swaps two variables), overlaps within the >>> collection of assigned-to variables are not safe! For instance, the >>> following program prints "[0, 2]": >>> >>> x = [0, 1] >>> i = 0 >>> i, x[i] = 1, 2 >>> print x >>> >>> Lorenzo Gatti >> >> Thank you for the explanation. I guess my question can be simplified as: >> >> First step: a, b = 0, 1 >> No problem here as a and b are assigned values. >> >> Second step: a, b = b, a + b >> >> Now my question is does b become a + b after a becomes 1 or while a >> stays at 0? >> >> As the assignment occurs simultaneously I suppose the answer is while a >> stays at 0. > > Read the previous response carefully and you'll answer your question. > The right hand side is EVALUATED in full before values are assignated to > the left hand side. Evaluating b, a+b results in 1, 1. The, those values > are assigned to a, b. Thank you very much. It's clear now. -- http://mail.python.org/mailman/listinfo/python-list