You cannot trust arithmetic anymore

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

You cannot trust arithmetic anymore

Post by dunbarx » Wed Dec 16, 2020 5:44 pm

Almost died trying to debug this one. Almost.

It turns out that in our universe 11.025 * 28 = 308.7.

No surprises there.

But although 308.7 / 11.025 gives "28", it seems that 308.7 div 11.025 gives "27". I used "div" in a procedure, and I could not find the calculation error in the flow of (what I call) my logic for the longest time.

Out in the nether world of the precision limit:

Code: Select all

on mouseUp
   set the numberFormat to "#.###############"
   put 308.7 / 11.025 into t1  --"28"
   put 308.7 div 11.025 into t2  --"27"
   put t1 - t2
end mouseUp
gives not "1", but rather "0.999999999999996".

I am shocked to find it matters at the near-integer level, assuming that is what is tripping up "div". But then why does it not trip up "/"?

You have to be careful when counting using your fingers and toes. Make sure you have approximately ten of each.

Is this a bug in "div"?

Craig
Last edited by dunbarx on Wed Dec 16, 2020 8:42 pm, edited 1 time in total.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

Re: You cannot trust arithmetic anymore

Post by dunbarx » Wed Dec 16, 2020 5:51 pm

So until someone tells me what I am doing wrong, I kludged a patch onto the instance that tripped me up by adding a small but apparently NOT insignificant "0.0000001" to every value where I use "div".

This will not matter in what I am doing. So instead of trying to get "28" out of 308.7 div 11.025 the old fashioned way, I am going to get it out of "308.700001". Works a treat.

Do I find every "div" I have ever used and patch there as well? This seems a bit untoward, however. :roll:

Craig

EDIT:

I wrote a test routine to check a LOT of random numbers with varying amounts of digits after the decimal point. Almost, but not quite all numbers have the issue with "div".

No integers do. Perhaps "div" must therefore be restricted to integers, unless the small kludge I mentioned above is included.

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 10102
Joined: Fri Feb 19, 2010 10:17 am

Re: You cannot trust arithmetic anymore

Post by richmond62 » Wed Dec 16, 2020 8:20 pm

Floating Point, Oh Floating Point . . .

is why BBC BASIC rocks, while the BASIC in an Amstrad stinks.

Russell & Whitehead worked out, about a century ago that 1 + 1 sometimes equals 1.

1 bottle of stout, 1 gin and tonic & 2 glasses of white wine.

TorstenHolmer
Posts: 58
Joined: Mon Oct 28, 2013 1:23 pm

Re: You cannot trust arithmetic anymore

Post by TorstenHolmer » Wed Dec 16, 2020 11:55 pm

RTFM :D

In the dictionary:
"While using non-integer number and divisor usually produces sensible results, mathematically, integer division is generally defined as a function over the integers, and the results using non-integers may not consistently be what you expect."

Cheers,
Torsten

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

Re: You cannot trust arithmetic anymore

Post by dunbarx » Thu Dec 17, 2020 1:52 am

Torsten.

There are other points made in the dictionary, especially;

"Divides one number by another and returns the integer part of the result." That is rather disingenuous.

But also:

"Use the div operator to do integer division." That is deceptively simple.

I have never had any issue with using "div" with decimal values. And I do a LOT of that in my own work with LC. Until now. And as I said, a good 5-10% of ALL floating point operations show the symptom. I cannot believe this has not come up before.

Anyway, I am kludging every single instance in all my scripts everywhere. Thank heavens for "Find and Replace".

Craig

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 10102
Joined: Fri Feb 19, 2010 10:17 am

Re: You cannot trust arithmetic anymore

Post by richmond62 » Thu Dec 17, 2020 9:27 am

RTFM
Not when drunk. 8)

And (as now sober), if the numberFormat is set to #.###############
why is the answer to 308.7 / 11.025 NOT 27.9365079 . . . ?

When I set up a stack and did THIS:

Code: Select all

on mouseUp
   set the numberFormat to "#.###############"
   put 308.7 / 11.025
end mouseUp
I got 27.999999999999

While the macOS calculator gave me 27.9365079 . . . (too lazy to type out all the other ultradecimals)

Which suggests that something is "a bit wonky" with LiveCode's Maths anyway.

Code: Select all

put 308.7 div 11.025
gives me 27, which explains the 0.99999999 . . . perfectly.

So the problem is with 308.7 / 11.025, and the answer should be 0.9365079

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 10102
Joined: Fri Feb 19, 2010 10:17 am

Re: You cannot trust arithmetic anymore

Post by richmond62 » Thu Dec 17, 2020 10:17 am

Just fired up my BBC Model B and did this:

BBC BASIC

Code: Select all

10 AA=(308.7 / 11.025)
20 PRINT AA
RUN
and got 28.

Code: Select all

10 AA=(308.7 / 11.025)
20 BB= (308.7 DIV 11.025)
30 PRINT AA
40 PRINT BB
RUN
and got 28 twice.

If you want to "get down and dirty" go here: https://clp.bbcrewind.co.uk/jsbeeb/index.html

Using an AMSTRAD emulator (if you should choose to ship me a real AMSTRAD computer for Christmas
you will have my wife's curses ringing in your ears for eternity) . . .

I get "Syntax error in 20" which means the thing does not like DIV.

https://www.retrovm.com/

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7393
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: You cannot trust arithmetic anymore

Post by jacque » Thu Dec 17, 2020 5:05 pm

I have never had any issue with using "div" with decimal values. And I do a LOT of that in my own work with LC. Until now. And as I said, a good 5-10% of ALL floating point operations show the symptom. I cannot believe this has not come up before.
It hasn't come up because it's behaving correctly. Div and / are not equivalent. Div returns the truncated result of a division, which is 27 here. A slash returns the complete result including decimal values.

You get 28 with "/" division because the result has more decimal digits than the math library can handle so it rounds up. Div uses the real result and returns the integer portion.

If you are doing a bulk replace, replace div with slash.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

Re: You cannot trust arithmetic anymore

Post by dunbarx » Thu Dec 17, 2020 5:35 pm

Jacque.

In my naïveté I assumed that since 11.025 * 28 = 308.7 exactly, then doing the "reverse" with the div operator ought to give my original integer argument back. Again, exactly. In other words, I assumed that integers were in play here since the calculation gave an integer result.

So the "truncated result of a division" , as you say, ought to give back the precise integer value of that division, exactly the one we see if one does the multiplication.

This begs the issue that computers have no fingers and toes. I know this, but did not consider it. So to your point. I think the answer lies not so much in the dictionary definition of "div", as in the fingers and toes thing.

Craig

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

Re: You cannot trust arithmetic anymore

Post by dunbarx » Thu Dec 17, 2020 5:50 pm

Jacque wrote:
If you are doing a bulk replace, replace div with slash.
I cannot, since I use div instead of slash exclusively to extract the integer portion of an argument, not, in those cases, to find the quotient. It seems difficult indeed to extract an answer by reversing an arithmetic process. I have to kludge this, to add a tiny value to my "dividends" to make "sensible" div calculations. I assume this gives the machine fingers and toes.

Mark W. Where are you?

Craig

EDIT. I want to say this more clearly. There are exactly 28 integral distinct "11.025's" in 308.7. I expected "div" to know that, and give me back my 28.

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7393
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: You cannot trust arithmetic anymore

Post by jacque » Thu Dec 17, 2020 6:39 pm

Okay, you do need the workaround. I assumed from Richmond's results that it wasn't an even division (I should have checked.) But it does show that the SANE library is approximating again.

Mark explained it once but that was a long time ago and I can't remember where I read it.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

Re: You cannot trust arithmetic anymore

Post by dunbarx » Thu Dec 17, 2020 6:50 pm

Jacque.

We design, engineer and manufacture custom architectural lighting systems. The project that most uses this sort of thing calculates how many actual physical objects fit into actual physical other objects. That is what I do a lot with LC. So if I know that 28 peaShooters can fit into someones pocket, I need to get that "28" back intact.

Craig

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: You cannot trust arithmetic anymore

Post by mwieder » Mon Dec 21, 2020 9:47 pm

Craig-

Still, replace *all* your "div" entries with "/".
Then use the trunc() function when necesssary to return just the truncated integer portion of the result.

You're not going to end up with 28.3 peashooters that way. Or 29.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

Re: You cannot trust arithmetic anymore

Post by dunbarx » Tue Dec 22, 2020 3:36 am

Mark.

Sure thing. I said in the original post:

Code: Select all

But although 308.7 / 11.025 gives "28"...
No problem fixing this, I was just surprised it needed fixing.

Craig

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10333
Joined: Wed May 06, 2009 2:28 pm

Re: You cannot trust arithmetic anymore

Post by dunbarx » Wed Dec 30, 2020 6:01 pm

Like I said, you cannot trust arithmetic any longer. On a new card with a tallish field and a button, put this in the button script:

Code: Select all

on mouseUp
   put 11.025 * 28 into temp --308.7 exactly
   put temp / 11.025 into fld 1
   put temp div 11.025 into line 2 of fld 1
   put trunc(temp / 11.025) into line 3 of fld 1
end mouseUp
You get:

Code: Select all

28
27
27
@Mark W.

The trunc thing does not cut it. So the original idea not to kludge the "div" operator by additional a tiny amount to its argument:

Code: Select all

put temp + 0.0001 div 11.025
to get my poor "28" back, actually is the only thing that works.

I added little bits to my values, all over my div world. But why doesn't, essentially, trunc(28) give 28? Fingers and toes, again, eh?

Craig

Post Reply