···88to be equal (e.g. when calculating the same result through different correct methods) often differ
99slightly, and a simple equality test fails. For example:
10101111- a = 0.1 + 0.2
1212- b = 0.15 + 0.15
1111+ a = 0.15 + 0.15
1212+ b = 0.1 + 0.2
1313 if(a == b) // can be false!
1414+ if(a >= b) // can also be false!
14151516Don't use absolute error margins
1617--------------------------------
···3132-----------------------
3233There are some important special cases where this will fail:
33343434-* When both `a` and `b` are zero. `0.0/0.0` is "not a number", which returns false for all comparisons.
3535-* When only `b` is zero, the division yields "infinity", which is greater than epsilon even when `a` is smaller.
3535+* When both `a` and `b` are zero. `0.0/0.0` is "not a number", which causes an exception on some platforms, or returns false for all comparisons.
3636+* When only `b` is zero, the division yields "infinity", which may also cause an exception, or is greater than epsilon even when `a` is smaller.
36373738Also, the result is not commutative (`nearlyEquals(a,b)` is not always the same as `nearlyEquals(b,a)`). To fix these problems, the code has to get a lot more complex, so we really need to put it into a function of its own:
3839
+1-1
content/formats/binary.html
···61616262Specifically, binary can only represent those numbers as a finite fraction where the denominator
6363is a power of 2. Unfortunately, this does not include most of the numbers that can be
6464-represented as finite fration in base 10, like 0.1.
6464+represented as finite fraction in base 10, like 0.1.
65656666| Fraction | Base | Positional Notation | Rounded to 4 digits| Rounded value as fraction | Rounding error |
6767|-|-|-|-|
+2-2
content/formats/integer.html
···88This works, but has a number of **severe drawbacks**:
991010* It's more work (and more opportunity for bugs) to get it right, especially in regard to [rounding modes](/errors/rounding/).
1111-* Integers have complete precision, but very limited range, and when they overflow, they usually "wrap around" silently, i.e. the largest integer plus 1 becomes zero (for unsigned ints) or the largest negative one (for signed). This is just about the worst possible behaviour when dealing with money, for obvious reasons.
1212-* The implicit decimal point is hard to change and extremely inflexible: if you store dollars as cents, it's simply impossible to support the [Bahraini dinar](http://en.wikipedia.org/wiki/Bahraini_dinar)(1 dinar = 1,000 Fils) at the same time. You'd have to store the position of the decimal point with the data - the first step in implementing your own (buggy, non-standard) limted-precision decimal [floating-point](/formats/fp/) format.
1111+* Integers have complete precision, but very limited range, and when they overflow, they usually "wrap around" silently, i.e. the largest integer plus 1 becomes zero (for unsigned ints) or the negative value with the largest magnitude (for signed). This is just about the worst possible behaviour when dealing with money, for obvious reasons.
1212+* The implicit decimal point is hard to change and extremely inflexible: if you store dollars as cents, it's simply impossible to support the [Bahraini dinar](http://en.wikipedia.org/wiki/Bahraini_dinar)(1 dinar = 1,000 Fils) at the same time. You'd have to store the position of the decimal point with the data - the first step in implementing your own (buggy, non-standard) limited-precision decimal [floating-point](/formats/fp/) format.
13131414Summary: **using integers is not recommended.** Do this only if there really is no [better alternative](/formats/exact/) at all.