This is not as simple as you think. It all boils down to representability.
Let's consider a simple example of 0.1
. That value is not exactly representable in double
. This is because double
is a binary representation rather than a decimal representation.
A double
value is stored in the form s*2^e
, where s
and e
are the significand and exponent respectively, both integers.
Back to 0.1
. That value cannot be exactly represented as a binary floating point value. No combination of significand and exponent exist that represent it. Instead the closest representable value will be used:
0.10000 00000 00000 00555 11151 23125 78270 21181 58340 45410 15625
If this comes as a shock I suggest the following references:
So, what to do? An obvious option is to switch to a decimal rather than binary representation. In Delphi that typically means using the Currency
type. Depending on your application that might be a good choice, or it might be a terrible choice. If you wish to perform scientific or engineering calculations efficiently, for instance, then a decimal type is not appropriate.
Another option would be to look at how Python handles this. The repr
function is meant, where possible, to yield a string with the property that eval(repr(x)) == x
. In older versions of Python repr
produced very long strings of the form 1.1000000000000001
when in fact 1.1
would suffice. Python adopted an algorithm that finds the shortest decimal expression that represents the floating point value. You could adopt the same approach. The snag is that the algorithm is very complex.