0

I want to convert a double to a string and only display needed decimals.

So I cannot use

d := 123.4
s := Format('%.2f', [d]);

As it display as the result is 123.40 when I want 123.4.

Here is a table of samples and expected result

|Double|Result as string|
-------------------------
|5     |5               |
|5.1   |5.1             |
|5.12  |5.12            |
|5.123 |5.123           |
Roland Bengtsson
  • 5,058
  • 9
  • 58
  • 99

2 Answers2

3

You can use the %g format string:

General: The argument must be a floating-point value. The value is converted to the shortest possible decimal string using fixed or scientific format. The number of significant digits in the resulting string is given by the precision specifier in the format string; a default precision of 15 is assumed if no precision specifier is present. Trailing zeros are removed from the resulting string, and a decimal point appears only if necessary. The resulting string uses the fixed-point format if the number of digits to the left of the decimal point in the value is less than or equal to the specified precision, and if the value is greater than or equal to 0.00001. Otherwise the resulting string uses scientific format.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
smooty86
  • 1,112
  • 7
  • 13
2

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.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490