Page 1 of 1

Math problem with DIV?

Posted: Sat Jan 01, 2011 6:10 pm
by shawn
Anyone else seen problems with DIV when used with decimals? I am using it to break an amount of money into change. It seems to mishandle the pennies on occasion.

Try the following code....

Code: Select all

put "1.30" into change
   put change div 20 into temp
   if temp > 0 then
      put temp  && "   Twenty Dollar Bill(s)" && return after list_change
      put change - (temp * 20) into change
   end if
   
   put change div 10 into temp
   if temp > 0 then
      put temp  && "   Ten Dollar Bill(s)" && return after list_change
      put change - (temp * 10) into change
   end if
   
   put change div 5 into temp
   if temp > 0 then
      put temp  && "   Five Dollar Bill(s)" && return after list_change
      put change - (temp * 5) into change
   end if
   
   put change div 1 into temp
   if temp > 0 then
      put temp  && "   One Dollar Bill(s)" && return after list_change
      put change - (temp * 1) into change
   end if
   
   put change div .25 into temp
   if temp > 0 then
      put temp  && "   Quarter(s)" && return after list_change
      put change - (temp * .25) into change
   end if
   
   put change div .10 into temp
   if temp > 0 then
      put temp  && "   Dime(s)" && return after list_change
      put change - (temp * .10) into change
   end if
   
   put change div .05 into temp
   if temp > 0 then
      put temp  && "   Nickels" && return after list_change
      put change - (temp * .05) into change
   end if
   
   answer change -- to verify what we have here
   put change div .01 into temp
   answer temp -- to verify DIV result
   if temp > 0 then
      put temp  && "   Pennies" && return after list_change
      put change - (temp * .01) into change
   end if
When it hits the "answer change" you will get 0.05 and it will also calculate 5 pennies. If you change the first line from "put 1.30 into change" to "put 2.30 into change" when you get to the "answer change" you will still get 0.05... however the DIV will now come back and say .01 goes into .05 only 4 times which obviously isn't correct.

This is on livecode build 1150 version 4.5.2.

Any ideas?

Shawn

FIxed a bug that was keeping it from calculating nickels properly. Still seeing the same issue though at 1.30 it calculates 1 nickel at 2.30 it calculates 4 pennies.

Re: Math problem with DIV?

Posted: Sat Jan 01, 2011 6:51 pm
by bn
Hi Shawn,

I see the same behavior as you do.

from the dictionary for DIV
Note: 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.
I think you run into this problem.

Kind regards
Bernd

Re: Math problem with DIV?

Posted: Sat Jan 01, 2011 7:01 pm
by bn
Hi Shawn,

Code: Select all

on mouseUp
   put "2.30" into change
   put round(change * 100) into change
      put change div 2000 into temp
      if temp > 0 then
            put temp  && "   Twenty Dollar Bill(s)" && return after list_change
            put change - (temp * 2000) into change
      end if
      
      put change div 1000 into temp
      if temp > 0 then
            put temp  && "   Ten Dollar Bill(s)" && return after list_change
            put change - (temp * 1000) into change
      end if
      
      put change div 500 into temp
      if temp > 0 then
            put temp  && "   Five Dollar Bill(s)" && return after list_change
            put change - (temp * 500) into change
      end if
      
      put change div 100 into temp
      if temp > 0 then
            put temp  && "   One Dollar Bill(s)" && return after list_change
            put change - (temp * 100) into change
      end if
      
      put change div 25 into temp
      if temp > 0 then
            put temp  && "   Quarter(s)" && return after list_change
            put change - (temp * 25) into change
      end if
      
      put change div 10 into temp
      if temp > 0 then
            put temp  && "   Dime(s)" && return after list_change
            put change - (temp * 10) into change
      end if
      
      put change div 5 into temp
      if temp > 0 then
            put temp  && "   Nickels" && return after list_change
            put change - (temp * 5) into change
      end if
      
      answer change -- to verify what we have here
      put change div 1 into temp
      answer temp -- to verify DIV result
      if temp > 0 then
            put temp  && "   Pennies" && return after list_change
            put change - (temp * 1) into change
      end if
   put list_change into field 1
end mouseUp
this works for 2.30

Kind regards

Bernd

Re: Math problem with DIV?

Posted: Sat Jan 01, 2011 7:14 pm
by shawn
Bernd,

Even if I convert everything to cents (so all integer math) DIV still works inconsistently. Works properly starting with:

put "1.30" into change

change that to

put "2.30" into change

and it doesn't work again.

Code: Select all

put "1.30" into change
   put change * 100 into change -- convert to pennies to make all math integer math
   put change div 2000 into temp
   if temp > 0 then
      put temp  && "   Twenty Dollar Bill(s)" && return after list_change
      put change - (temp * 2000) into change
   end if
   
   put change div 1000 into temp
   if temp > 0 then
      put temp  && "   Ten Dollar Bill(s)" && return after list_change
      put change - (temp * 1000) into change
   end if
   
   put change div 500 into temp
   if temp > 0 then
      put temp  && "   Five Dollar Bill(s)" && return after list_change
      put change - (temp * 500) into change
   end if
   
   put change div 100 into temp
   if temp > 0 then
      put temp  && "   One Dollar Bill(s)" && return after list_change
      put change - (temp * 100) into change
   end if
   
   put change div 25 into temp
   if temp > 0 then
      put temp  && "   Quarter(s)" && return after list_change
      put change - (temp * 25) into change
   end if
   
   put change div 10 into temp
   if temp > 0 then
      put temp  && "   Dime(s)" && return after list_change
      put change - (temp * 10) into change
   end if
   
   put change div 5 into temp
   if temp > 0 then
      put temp  && "   Nickel(s)" && return after list_change
      put change - (temp * 5) into change
   end if
  

   put change div 1 into temp
   if temp > 0 then
      put temp  && "   Penny(s)" && return after list_change
      put change - (temp * 1) into change
   end if
   
   put list_change into field "list_change"
   
.

Re: Math problem with DIV?

Posted: Sat Jan 01, 2011 7:28 pm
by shawn
Added the round function like in your example and it seems to work now. It is kind of odd that the math engine isn't coming up with a whole number for 2.30 * 100.

Thanks,

Shawn

Re: Math problem with DIV?

Posted: Sat Jan 01, 2011 7:31 pm
by bn
Hi Shawn,

note

Code: Select all

put round(change * 100) into change
in the code I posted. Then it works.

Integer math is difficult for computers because internally they do it all with floating point operations. But others know more about it.

Kind regards

Bernd

Re: Math problem with DIV?

Posted: Sat Jan 01, 2011 8:03 pm
by shawn
Bernd,

Sure, but if you have LiveCode multiple 2.30 * 100 and give you the answer it gives you an integer.

It is confusing and inconsistent that what it tells you the answer is isn't really what it is using for the answer in later calculations.

Thanks again for the help,

Shawn

Re: Math problem with DIV?

Posted: Sat Jan 01, 2011 8:51 pm
by bn
Hi Shawn,

Code: Select all

on mouseUp
   set the numberformat to ".##########################"
   put 2.3 * 100 into field 1
end mouseUp
try this

Kind regards

Bernd

Re: Math problem with DIV?

Posted: Wed Jan 26, 2011 11:48 pm
by jsburnett
Very interesting behavior.

I did notice that if you change the pennies to:

put (change/0.01) into temp
if temp > 0 then
put temp && " Pennies" && return after list_change
put change - (temp * .01) into change
end if

answer list_Change

It works all the time. At least with my testing.
(or not?).
JSB

Re: Math problem with DIV?

Posted: Thu Jan 27, 2011 1:53 pm
by BvG
This is silly. the amounts are tiny, the numbers are integer and the calculation is explicitely trashing all non-integer results. I filed a bug: http://quality.runrev.com/qacenter/show_bug.cgi?id=9346


as a workaround, always use the round function on each calculation for the followup amount. see my own test code:

Code: Select all

on mouseUp
   put field "money" * 100 into theChange
   put theChange into theOriginal
   put "2000,1000,500,100,50,25,10,5,2,1" into MoneyList
   put "20 bucks,ten bucks,five bucks,one buck,half a buck,quarter buck,ten dimes,five dimes,two dimes,one dime" into moneyNames
   put 0 into theItem
   repeat for each item theItem in moneyList
      add one to theItemOffset
      put theChange div theItem into temp
      if temp > 0 then
         put temp && "piece/s of" && item theItemOffset of moneyNames & return after theResult
         put round(theChange - temp * theItem) into theChange
      end if
   end repeat
   put 0 into resultSum
   repeat for each line theLine in theResult
      if the number of words of theLine > 0 then
         put item itemoffset(word 4 to -1 of theLine,moneyNames) of moneyList into theMultiplier
         add word 1 of theLine * theMultiplier to resultSum
      end if
   end repeat
   put theOriginal && "original amount" & return & resultSum && "calculated amount" & return & return before theResult
   put theResult into field list_change
   
end mouseUp

Re: Math problem with DIV?

Posted: Thu Jan 27, 2011 3:08 pm
by FourthWorld
BvG wrote:This is silly. the amounts are tiny, the numbers are integer and the calculation is explicitely trashing all non-integer results. I filed a bug: http://quality.runrev.com/qacenter/show_bug.cgi?id=9346
Thank you for that.

Computer science types are quick to apologize for the limits of a machine too stupid to count past 1, but programming languages serve the goals of humans, not the other way around. Simple arithmetic like this should be corrected for; if it can be done in script, it can be done in the engine.

Re: Math problem with DIV?

Posted: Thu Jan 27, 2011 6:03 pm
by mwieder
Well, unfortunately it's not something that can be "fixed". There are ways to deal with this by rounding, but you have to be careful where you round or you can lose precision in the calculations and come up with the wrong results. It's not a LC problem as such - you're reaching the limits of computer calculation. It's a matter of trying to simulate an analog world in a digital computer - quantizing errors can build up.

Here's some background info
http://en.wikipedia.org/wiki/Machine_epsilon