Wed 16 Aug 2006
Do the math ... or when is 156.14 != 156.14 ?
Category : Technology/maths.txt
This is a Cash Disbursement voucher in Luca :
I have a rule that says you can't save a voucher unless the debits and credits balance. So, here we have $156.14 being paid out of a checking account, recorded against an equal $156.14 in expenses. Yet the Save button refuses to be enabled. What is going on here?
Looking a bit closer at the objects :
NSLog(@"vouAmount = %f", [vouAmount doubleValue]);
NSLog(@"ttlAmount = %f", [ttlAmount doubleValue]);
we get :
Luca vouAmount = 156.140000
Luca ttlAmount = 156.140000
It's as we would expect but it remains puzzling, so we zoom even closer :
NSLog(@"vouAmount = %1.24f", [vouAmount doubleValue]);
NSLog(@"ttlAmount = %1.24f", [ttlAmount doubleValue]);
we get :
Luca vouAmount = 156.140000000000014779288904
Luca ttlAmount = 156.139999999999986357579473
The vouAmount is taken straight off the object. The total column has a rounding function applied to it, but still it's just one line item, for simplicity's sake. So both items are off the expected figure of 156.14. They never balance.
This happens only at certain values, not all the time. It happens because "real numbers" in digital computations are only a very close approximation to the mathematical concept of real numbers. The difference is infinitesimally small (my favourite expression in engineering school), but it's there all the same. It's what throws us off.
The solution is to round both numbers before comparing them, even the one entered exactly as 156.14.. But we have to take care to do the rounding at lots of places, not just when the value is entered. For example, you do rounding when one value is multiplied by another. But what happens when you divide a dollar by three. You lose that last infinitesimally small fraction of a cent because computers work with discrete values, not a continuum.
So, that's why building such systems, mundane though they seem, is hard. It's a craft. It's precision work. But it's not the kind that will win Apple Design Awards at WWDC.