Re: [Tutor] Fraction - differing interpretations for number and string - presentation
On 17 April 2015 at 03:29, Steven D'Aprano wrote: > On Thu, Apr 16, 2015 at 03:11:59PM -0700, Jim Mooney wrote: > >> So the longer numerator and denominator would, indeed, be more accurate if >> used in certain calculations rather than being normalized to a float - such >> as in a Fortran subroutine or perhaps if exported to a machine with a >> longer bit-length? That's mainly what I was interested in - if there is any >> usable difference between the two results. If it's okay to use float and then go onto machines with higher/lower precision then the extra precision must be unnecessary in which case why bother with the Fraction type? If you really need to transfer your float from one program/machine to another then why not just send the decimal representation. Your 64-bit float should be able to round-trip to decimal text and back for any IEEE-754 compliant systems. Writing it as a fraction doesn't gain any extra accuracy. (BTW Python the language guarantees that float is always an IEEE-754 64-bit float on any machine). When you use floats the idea is that you're using fixed-width floating point as an approximation of real numbers. You're expected to know that there will be some rounding and not consider your computation to be exact. So the difference between 1.64 and the nearest IEEE-754 64-bit binary float should be considered small enough not to worry about. It's possible that in your calculations you will also be using functions from the math module such as sin, cos, etc. and these functions cannot be computed *exactly* for an input such as 1.64. However they can be computed up to any desired finite precision so we can always get the nearest possible float which is what the math module will do. When you use the fractions module and the Fraction type the idea is that floating point inexactness is unacceptable to you. You want to perform *exact* arithmetic and convert from other numeric types or text exactly. You won't be able to use functions like sin and cos but that's no loss since you wouldn't be able to get an exact rational result there anyway. Because the Fractions module is designed for the "I want everything to be exact" use case conversion from float to Fraction is performed exactly. Conversion from string or Decimal to Fraction is also exact. The Fraction will also display its exact value when printed and that's what you're seeing. If you really want higher accuracy than float consider ditching it altogether in favour of Fraction which will compute everything you want exactly. However there's no point in doing this if you're also mixing floats into the calculations. float+Fraction coerces to float discarding accuracy and then calculates with floating point rounding. If that's acceptable then don't bother with Fraction in the first place. If not make sure you stick to only using Fraction. > You're asking simple questions that have complicated answers which > probably won't be what you are looking for. But let's try :-) > > Let's calculate a number. The details don't matter: > > x = some_calculation(a, b) > print(x) > > which prints 1.64. Great, we have a number that is the closest possible > base 2 float to the decimal 164/100. If we convert that float to a > fraction *exactly*, we get: > > py> Fraction(1.64) > Fraction(738590337613, 4503599627370496) > > So the binary float which displays as 1.64 is *actually* equal to > 738590337613/4503599627370496, which is just a tiny bit less than > the decimal 1.64: > > py> Fraction(1.64) - Fraction("1.64") > Fraction(-11, 112589990684262400) > > That's pretty close. The decimal value that normally displays as 1.64 is > perhaps more accurately displayed as: > > py> "%.23f" % 1.64 > '1.63990230037' > > but even that is not exact. Just to add to Steven's point. The easiest way to see the exact value of a float in decimal format is: >>> import decimal >>> decimal.Decimal(1.64) Decimal('1.6399023003738329862244427204132080078125') > The reality is that very often, the difference > isn't that important. The difference between > > 1.64 inches > > and > > 1.63990230037 inches > > is probably not going to matter, especially if you are cutting the > timber with a chainsaw. I once had a job surveying a building site as an engineer's assistant. I'd be holding a reflector stick while he operated the laser sight machine (EDM) from some distance away and spoke to me over the radio. He'd say "mark it 10mm to the left". The marker spray would make a circle that was about 100mm in diameter. Then I would get 4 unevenly shaped stones (that happened to be lying around) and drop them on the ground to mark out the corners of a 1500mm rectangle by eye. Afterwards the excavator would dig a hole there using a bucket that was about 1000mm wide. While digging the stones would get moved around and the operator would end up just vaguely guessing where the original marks had been. The engineer was absolutely insistent that it h
Re: [Tutor] Fraction - differing interpretations for number and string - presentation
On Thu, Apr 16, 2015 at 03:11:59PM -0700, Jim Mooney wrote: > So the longer numerator and denominator would, indeed, be more accurate if > used in certain calculations rather than being normalized to a float - such > as in a Fortran subroutine or perhaps if exported to a machine with a > longer bit-length? That's mainly what I was interested in - if there is any > usable difference between the two results. You're asking simple questions that have complicated answers which probably won't be what you are looking for. But let's try :-) Let's calculate a number. The details don't matter: x = some_calculation(a, b) print(x) which prints 1.64. Great, we have a number that is the closest possible base 2 float to the decimal 164/100. If we convert that float to a fraction *exactly*, we get: py> Fraction(1.64) Fraction(738590337613, 4503599627370496) So the binary float which displays as 1.64 is *actually* equal to 738590337613/4503599627370496, which is just a tiny bit less than the decimal 1.64: py> Fraction(1.64) - Fraction("1.64") Fraction(-11, 112589990684262400) That's pretty close. The decimal value that normally displays as 1.64 is perhaps more accurately displayed as: py> "%.23f" % 1.64 '1.63990230037' but even that is not exact. So which is the "right" answer? That depends. (1) It could be that our initial calculation some_calculation(a, b) actually was 164/100, say, in which case the *correct* result should be decimal 1.64 = Fraction("1.64") and the 7385blahblahblah/blahblahblah is just an artifact of the fact that floats are binary. (2) Or it could be that the some_calculation(a, b) result actually was 738590337613/4503599627370496, say, in which case it is a mere coincidence that this number displays as 1.64 when treated as a binary float. The long 7385blahblahblah numerator and denominator is exactly correct, and decimal 1.64 is a approximation. There is no way of telling in advance which interpretation is correct. You need to think about the calculation you performed and decide what it means, not just look at the final result. Although... 9 times out of 10, if you get something *close* to an exact decimal, a coincidence is not likely. If you get exactly 0.5 out of a calculation, rather than 0.50001, then it probably should be exactly 1/2. *Probably*. The reality is that very often, the difference isn't that important. The difference between 1.64 inches and 1.63990230037 inches is probably not going to matter, especially if you are cutting the timber with a chainsaw. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fraction - differing interpretations for number and string - presentation
The whole point of the discussion is that this is *not* a presentation issue. Fraction(1.64) and Fraction("1.64") *are* two different numbers because one gets constructed from a value that is not quite 1.64. Wolfgang Maier -- So the longer numerator and denominator would, indeed, be more accurate if used in certain calculations rather than being normalized to a float - such as in a Fortran subroutine or perhaps if exported to a machine with a longer bit-length? That's mainly what I was interested in - if there is any usable difference between the two results. Jim The Paleo diet causes Albinism ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fraction - differing interpretations for number and string - presentation
On 04/16/2015 01:24 PM, Jim Mooney wrote: Is this "inaccurate"? Well, in the sense that it is not the exact true mathematical result, yes it is, but that term can be misleading if you think of it as "a mistake". In another sense, it's not inaccurate, it is as accurate as possible (given the limitation of only having a certain fixed number of bits). -- Steve --- Understood about the quondam inexactness of floating point bit representation. I was just wondering why the different implementation of representing it when using Fraction(float) as opposed to using Fraction(string(float)). You didn't use str(float), you used a simple str. So there was no quantization error since it was never converted to binary floating point. If you have a number that happens to be an exact decimal number, don't convert it via float(). Either convert it via Decimal() or convert it directly to fraction. In terms of user presentation, the string usage has smaller numbers for the ratio, so it would be more understandable and should, I assume, be chosen for GUI display. Presumably you didn't read my message. When you use a literal 1.64 in your code, you're telling the compiler to call the float() function on the token. You've already forced the quantization error. Nothing to do with the fraction class. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fraction - differing interpretations for number and string - presentation
On Apr 16, 2015 1:42 PM, "Jim Mooney" wrote: > Understood about the quondam inexactness of floating point bit > representation. I was just wondering why the different implementation of > representing it when using Fraction(float) as opposed to using > Fraction(string(float)). Ah. Correction. You want to say: .. using Fraction(float) as opposed to using Fraction(**string**). ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fraction - differing interpretations for number and string - presentation
On 16.04.2015 19:24, Jim Mooney wrote: Understood about the quondam inexactness of floating point bit representation. I was just wondering why the different implementation of representing it when using Fraction(float) as opposed to using Fraction(string(float)). In terms of user presentation, the string usage has smaller numbers for the ratio, so it would be more understandable and should, I assume, be chosen for GUI display. The whole point of the discussion is that this is *not* a presentation issue. Fraction(1.64) and Fraction("1.64") *are* two different numbers because one gets constructed from a value that is not quite 1.64. What sense would it make for Fraction(1.64) to represent itself inexactly ? However, if you really want a shortened, but inexact answer: Fractions have a limit_denominator method that you could use like so: >>> Fraction(1.64).limit_denominator(25) Fraction(41, 25) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fraction - differing interpretations for number and string - presentation
> > Is this "inaccurate"? Well, in the sense that it is not the exact true > mathematical result, yes it is, but that term can be misleading if you > think of it as "a mistake". In another sense, it's not inaccurate, it is > as accurate as possible (given the limitation of only having a certain > fixed number of bits). > -- > Steve > --- Understood about the quondam inexactness of floating point bit representation. I was just wondering why the different implementation of representing it when using Fraction(float) as opposed to using Fraction(string(float)). In terms of user presentation, the string usage has smaller numbers for the ratio, so it would be more understandable and should, I assume, be chosen for GUI display. -- Jim The Paleo diet causes Albinism ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor