LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!
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.
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.
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.
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
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"
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.
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
Various teststacks and stuff:
http://bjoernke.com
Chat with other RunRev developers:
chat.freenode.net:6666 #livecode
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.
Richard Gaskin LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
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.