Reputation: 631
How do I format a number into a string so that the number of digits after the decimal point depends on the number of digits before the decimal point?
The aim is to output a number in a human-friendly way. For example, if an output looks like this: "1022.564 GB", then this is quite difficult to understand in contrast to "1023 GB". Of course, this only makes sense if the number of gigabytes is very high. If you move in the low terabyte range, it would look like this: "1 TB" (too little information). A flexible format would therefore be very appropriate here (e.g.: "1.234 TB").
To make it clear how this has to work, an example algorithm:
Console.WriteLine(FormatFloating(.123456));
Console.WriteLine(FormatFloating(1.23456));
Console.WriteLine(FormatFloating(12.3456));
Console.WriteLine(FormatFloating(123.456));
Console.WriteLine(FormatFloating(1234.56));
Console.WriteLine(FormatFloating(12345.6));
Console.WriteLine(FormatFloating(123456));
Console.WriteLine(FormatFloating(double.NaN));
// Algorithm:
static string FormatFloating(double value, int maxDecimals = 4) =>
value.ToString(double.IsNormal(value)
? $"F{Math.Max(0, maxDecimals + 1 - Math.Truncate(Math.Abs(value)).ToString(CultureInfo.InvariantCulture).Length)}"
: string.Empty);
Output (hypothetical):
0.1234
1.2345
12.345
123.45
1234.5
12345
123456
NaN
Does C# (10.0, .NET 6.0) have a native format specifier or a custom format that honors this algorithm?
Upvotes: 0
Views: 183
Reputation: 1199
This question seems related to the concept of significant figures. A native format specifier for that is "G".
123.4567.ToString("G5") // output: 123.46
Of your hypothetical output, only 0.1234 and 123456 would not be given then. However, for those cases you would probably want to convert to another unit of measurement, for example 123.46KB instead of 0.1234MB and 123.46GB instead of 123456MB. (Also notice that this format specifier rounds instead of truncates.)
Upvotes: 1