Page 1 of 3

You cannot trust arithmetic anymore

Posted: Wed Dec 16, 2020 5:44 pm
by dunbarx
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

Re: You cannot trust arithmetic anymore

Posted: Wed Dec 16, 2020 5:51 pm
by dunbarx
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.

Re: You cannot trust arithmetic anymore

Posted: Wed Dec 16, 2020 8:20 pm
by richmond62
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.

Re: You cannot trust arithmetic anymore

Posted: Wed Dec 16, 2020 11:55 pm
by TorstenHolmer
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

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 1:52 am
by dunbarx
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

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 9:27 am
by richmond62
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

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 10:17 am
by richmond62
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/

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 5:05 pm
by jacque
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.

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 5:35 pm
by dunbarx
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

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 5:50 pm
by dunbarx
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.

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 6:39 pm
by jacque
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.

Re: You cannot trust arithmetic anymore

Posted: Thu Dec 17, 2020 6:50 pm
by dunbarx
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

Re: You cannot trust arithmetic anymore

Posted: Mon Dec 21, 2020 9:47 pm
by mwieder
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.

Re: You cannot trust arithmetic anymore

Posted: Tue Dec 22, 2020 3:36 am
by dunbarx
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

Re: You cannot trust arithmetic anymore

Posted: Wed Dec 30, 2020 6:01 pm
by dunbarx
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