# [Tutor] the binary math "wall"

Lowell Tackett lowelltackett at yahoo.com
Wed Apr 21 04:11:24 CEST 2010

```>From the virtual desk of Lowell Tackett

--- On Tue, 4/20/10, Steven D'Aprano <steve at pearwood.info> wrote:

> From: Steven D'Aprano <steve at pearwood.info>
> Subject: Re: [Tutor] the binary math "wall"
> To: tutor at python.org
> Date: Tuesday, April 20, 2010, 7:39 PM
> On Wed, 21 Apr 2010 02:58:06 am
> Lowell Tackett wrote:
> > I'm running headlong into the dilemma of binary math
> representation,
> with game-ending consequences, e.g.:
> > >>> 0.15
> >
> > 0.14999999999999999
> >
> > Obviously, any attempts to manipulate this value,
> under the misguided
> > assumption that it is truly "0.15" are ill-advised,
> with inevitable
>
> That really depends on what sort of manipulation you are
> doing.
>
> >>> x = 0.15
> >>> x
> 0.14999999999999999
> >>> x*100 == 15
> True
>
> Seems pretty accurate to me.
>
> However:
>
> >>> 18.15*100 == 1815
> False
>
>
> The simplest, roughest way to fix these sorts of problems
> (at the risk
> of creating *other* problems!) is to hit them with a
> hammer:
>
> >>> round(18.15*100) == 1815
> True

Interestingly, this is the [above] result when I tried entered the same snippet:

Python 2.5.1 (r251:54863, Oct 14 2007, 12:51:35)
[GCC 3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)] on linux2
>>> round(18.15)*100 == 1815
False
>>>

But...I'm just offering that for its' curiosity value, not to contradict your comments or the case you are making.
>
> [...]
> > What I'm shooting...is an algorithm
> that converts a
> > deg/min/sec formatted number to decimal degrees.
> It [mostly] worked...which exposed the flaw.
>
> I'm afraid that due to the nature of floating point, this
> is a hard
> problem. Even the professionals at Hewlett-Packard's
> scientific
> calculator division don't always get it right, and they are
> *extremely*
> careful:
>
>

Interesting that you raise the *hallowed* 48GX as a standard.  I have one (of the two I own) sitting next to me here, and have been using it as the bar against which to compare my computer.  Using the HMS+/-/-> etc. functions, I get pretty darned accurate results.  (Wish I'd known in time that HP was gonna throw the "48's" down the drain-I would own a lot more than two of them!)

> The best result I can suggest is, change the problem! Don't
> pass
> degrees-minutes-seconds around using a floating point
> value, but as a
> tuple with distinct (DEG, MIN, SEC) integer values. Or
> create a custom
> class.
>
> But if you really need D.MMSS floats, then something like
> this should be
> a good start.:
>
> def dms2deg(f):
>     """Convert a floating point number formatted
> as D.MMSS
>     into degrees.
>     """
>     mmss, d = math.modf(f)
>     assert d == int(f)
>     if mmss >= 0.60:
>         raise ValueError(
> < .60 but got %f' % mmss)
>     mmss *= 100
>     m = round(mmss)
>     if m >= 60:
> expected < 60 but got %d' % m)
>     s = round((mmss - m)*100, 8)
>     if not 0 <= s < 60.0:
> expected < 60.0 but got %f' % s)
>     return d + m/60.0 + s/3600.0
>
>
> >>> dms2deg(18.15)
> 18.25
> >>> dms2deg(18.1515)
> 18.254166666666666
>
>
> which compares well to my HP-48GX:
>
> 18.15 HMS->
>
> gives 18.25, and:
>
> 18.1515 HMS->
>
> gives 18.2541666667.
>
>
> Note though that this still fails with some valid input. I
> will leave
> fixing it as an exercise (or I might work on it later, time
>
> permitting).
>
>
> --
> Steven D'Aprano
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>

What you've provided with your comments is more of what I've received wholesale in this entire discourse--an incredible wealth of new insight and ways of looking at the problem.  Don't think you grasp how new I am at this, and how even what little I've tried to "pull off"-on my own-is way out at the edge of the "box" for me.  Someone wondered if performance was an issue that could effect my choices.  Well, no.  Basically, I want to manipulate [land] survey data - you know, coordinates and stuff - so the goal here is coding those things that will yield accurate number results.

I've been handed, in response, comments about the challenges going all the way back to the early days of Fortran, stuff I had no concept of.  This is all fantastic, and it's gonna take a long time for me to assimilate and absorb what has been offered.  Even your comment concerning creating a class--my reaction is "Oh, oh--classes?  What'da I do NOW?!"  But, I've been given a great deal to chew on, and the implications go way beyond the scope of my original query.

Did I get what I asked for when I posed my question?  I'd say so...about 10X!  Now I gotta go to work and gain some good knowledge out of this mountain of advice that's been piled on my desk!

Thanks, all...

```