formatting a float or double in a string with all significant digits kept

Jon Degenhardt jond at noreply.com
Wed Oct 9 07:16:43 UTC 2019


On Wednesday, 9 October 2019 at 05:46:12 UTC, berni44 wrote:
> On Tuesday, 8 October 2019 at 20:37:03 UTC, dan wrote:
>> But i would like to be able to do this without knowing the 
>> expansion of pi, or writing too much code, especially if 
>> there's some d function like writeAllDigits or something 
>> similar.
>
> You can use the property .dig to get the number of significant 
> digits of a number:
>
> writeln(PI.dig); // => 18
>
> You still need to account for the numbers before the dot. If 
> you're happy with scientific notation you can do:
>
> auto t = format("%.*e", PI.dig, PI);
> writeln("PI = ",t);

Using the '.dig' property is a really nice idea and looks very 
useful for this. A clarification though - It's the significant 
digits in the data type, not the value. (PI is 18 because it's a 
real, not a double.) So:

     writeln(1.0f.dig, ", ", float.dig);  =>  6, 6
     writeln(1.0.dig, ", ", double.dig);  => 15, 15
     writeln(1.0L.dig, ", ", real.dig);   => 18, 18

Another possibility would be to combine the '.dig' property with 
the "%g" option, similar to the use "%e" shown. For example, 
these lines:

     writeln(format("%0.*g", PI.dig, PI));
     writeln(format("%0.*g", double.dig, 1.0));
     writeln(format("%0.*g", double.dig, 100.0));
     writeln(format("%0.*g", double.dig, 1.00000001));
     writeln(format("%0.*g", double.dig, 0.00000001));

produce:

     3.14159265358979324
     1
     100
     1.00000001
     1e-08

Hopefully experimenting with the different formatting options 
available will yield one that works for your use case.


More information about the Digitalmars-d-learn mailing list