How to format a double with as many as significant digits as possible?
I wa开发者_开发知识库nt to format a double value with as many digits as necessary to stay the same value. I do not want to use exponential notation, because the receiver of the string needs floating point notation.
Examples:
12.0 -> "12"
12.20300 -> "12.203"
EDIT: The Round-trip specifier "R" seems to do what I need. At least with the number I tested with, it worked as expected.
You can use String.Format with a custom formatting string to tell the formatter to print it exactly how you want it. In this case, you want to use a modifier along the lines of 0.################
. This formatter essentially specifies that the number should have at least one digit before the decimal point, and up to (but not necessarily) sixteen digits after it. Unfortunately you have to have a maximum, denoted by the number of #
symbols, but 16 should be more than enough.
String.Format("{0:0.################}", 12.20300);
Format(x, "0.################") is very close, but there is some non-zero garbage after the significant digits that makes cDbl(Format(x, "0.################")) <> x
for most fractions.
You can get a lot more digits to the right of the decimal point this way, but it's not really practical (since they are garbage digits) and probably not what you're looking for:
For i = 1 To ndigits
s = s & Math.Floor(x * (10 ^ i)) Mod 10
Next i
Even with this, you probably won't be able to convert from double to string and back to double, and make them equal. The only way I know to do that is scientific notation or hex.
It can't really be done. Not trivially anyway and not using Doubles
. Doubles simply don't have enough digits for you to display any number which is probably why scientific notation is used to display the values when you simply call .ToString()
The output we get for doubles is in scientific notation because that better represents the value. Using this code as an example....
double testValue = 9123456789012345678.234;
string formatStr = "{0:0.####################################################},{1}";
Debug.WriteLine(String.Format(formatStr, testValue, testValue));
The output we get is:
9123456789012350000,9.12345678901235E+18
Neither is the actual number we started with. If you ignore really big numbers, I think you'll find that the examples you've posted don't require you to do anything.
Debug.WriteLine(12.0d + " == " + String.Format("{0} == {1:0.########################}", 12.0d, 12.0d));
Debug.WriteLine(12.20300d + " == " + String.Format("{0} == {1:0.########################}", 12.20300d, 12.20300d));
Debug.WriteLine(-00.2900d + " == " + String.Format("{0} == {1:0.########################}", -00.2900d, -00.2900d));
Debug.WriteLine(99999999999999999999999d + " == " + String.Format("{0} == {1:0.########################}", 99999999999999999999999d, 99999999999999999999999d));
12 == 12 == 12
12.203 == 12.203 == 12.203
-0.29 == -0.29 == -0.29
1E+23 == 1E+23 == 100000000000000000000000
In the first three examples, whether you display it with WriteLine directly, use String.Format with no format string, or use "0.########" the output is what you want. The only situation where the value is different is in the fourth case where the default behavior is to show scientific notation. Changing that behavior will give you numbers with additional zeros where you expect meaningful numbers; but it can be accomplished as Samir showed with the format string.
精彩评论