Float equality? (was: [BUG] Float NaN's)

Jarvis, Robert P. (Bob) (Contingent) bob.jarvis at timken.com
Tue Sep 14 18:13:48 UTC 2004


The best practice I'm aware of for handling equality calculations with
Floats is avoid them completely.  You should establish what you consider to
be an acceptable epsilon value based on your understanding of your data and
use it as follows:

	maxEpsilon = 0.000001.
		.
		.
		.
	(f1 - f2) abs < maxEpsilon
		ifTrue: ["f1 and f2 are approximately equal"]
		ifFalse: ["f1 and f2 are not approximately equal"]

The values that f1 and f2 could take on will affect what an appropriate
epsilon would be.  For example, if f1 and f2 are guaranteed to be in the
range of -10.0 to +10.0 then 0.000001 might be an appropriate epsilon.
However, if f1 and f2 will both be > 1e100 then an appropriate epsilon might
be more like 1e94.

Do not under any circumstances use floating point numbers in financial
calculations.  Floats are imprecise, often only approximate, and utterly
inappropriate for any calculation where all the fiddly little decimal places
really count.

Here's a quote of a post I made in comp.lang.smalltalk some years ago on
this subject (thanks, Google!):

>Malcolm Macgregor wrote in message ...
>>What happens if you have $1.01  in an account and gain 50% interest?
>>You should then have $1.515. Is this rounded up or down, or left as it
>>is for further transactions? Surely the only fair way is to use floating
>>point with the largest number of places after the decimal place being
>>used, then round up or down to 2 d.p. at the end of the day?
>
><sigh>  I know this must be a troll, but...
>
>This does not require the use of a Float.  In Smalltalk I'd use either a
>Fraction or a ScaledDecimal.  Your test case with ScaledDecimals (using
>Dolphin Smalltalk 3.02) is
>
>    balance := 1.01s.    "Produces a ScaledDecimal with fraction of 101/100
>and scale of 2"
>    balance := balance * 1.5s.    "= ScaledDecimal with fraction of 303/200
>and scale of 2"
>    balance := balance asScaledDecimal: 4.    "= ScaledDecimal w/fraction
of
>303/200 and scale of 4"
>
>This loses no precision, suffers from no rounding errors, and scales no
>matter how large your values.  Try the following using floating point:
>
>    Your bank balance is 98765432109876543210.23
>    You gain 27.25% interest.
>    What's your new balance?
>
>    Using ScaledDecimals it's 125679012359817901235.017675
>    Using floats it's 125679012359817900000.0
>
>    Golly...do you think anyone'll notice that little thousand+
>(dollar/pound/peso/whatever) error?
>
>For those who argue that this is a contrived example (it is) and that bank
>balances never get this large (I don't know if they do or don't), consider
>this: numbers like this aren't static, and eventually bank balances *will*
>grow to be this large.  Bank balances calculated in Italian lire, Hong Kong
>dollars, or some obscure currency like West Wurglian wombats may already
>well be this large - again, I don't know.  And I'll bet that you don't
>either.  It's the kind of thing that isn't an issue - until, that is, the
>guy in the *really* nice suit, shiny shoes, and fangs summons you to his
>spacious lair and starts the conversation with "We'll be recording your
>deposition today, Mr. Programmer.  I'm sure you understand...".

-----------------------------------------
**********************************************************************
PLEASE NOTE: The above email address has recently changed from a previous
naming standard -- if this does not match your records, please update them
to use this new name in future email addressed to this individual.    This
message and any attachments are intended for the   individual or entity
named above. If you are not the intended  recipient, please do not forward,
copy, print, use or disclose this   communication to others; also please
notify the sender by   replying to this message, and then delete it from
your system.     The Timken Company
**********************************************************************




More information about the Squeak-dev mailing list