Tostring("000.0") Generating Wrong Value
In My C# Console Application, I Want to Convert Double Variable to String Type. but Resultant String Variable Should Have at Least 3 Digit to Left of Decimal...
In my c# console application, I want to convert double variable to string type. but resultant string variable should have at least 3 digit to left of decimal point and one digit to right of it. example: 3.4569 should converted to "003.4"
It works for above example, but throws wrong result for following conversion.
double Num = Math.Pow((3 + Math.Sqrt(5)), N); //6578336356630531.0 for N=22
string StringNum = Num .ToString("000.0");
It results..
StringNum ="6578336356630530.0";
but it would be..
StringNum ="6578336356630531.0";
How do i get exact string value for these type of numbers??
//decimal Num=Convert.ToDecimal (Math.Pow((3 + Math.Sqrt(5)), N));
//this conversion also looses original value
Thanx..
6 Answers
The trouble is the value you're storing is exactly 6578336356630531. There is no double value closer to 6578336356630530. So the output is correct for the data present at execution time.
From the documentation:
All floating-point numbers also have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number. A Double value has up to 15 decimal digits of precision, although a maximum of 17 digits is maintained internally.
You're quibbling about the 16th digit.
I have a handy class which lets you see the exact value of any double.
If you need more precision than that, use decimal instead of double. Note that decimal has a smaller range but higher precision.
Can you use a decimal?
decimal Num = 6578336356630531.0M;
string StringNum = Num .ToString("000.0");
double is a float which approximates precision. See here.
Article excerpt:
Floating-Point Values and Loss of Precision
Remember that a floating-point number can only approximate a decimal number, and that the precision of a floating-point number determines how accurately that number approximates a decimal number. By default, a Double value contains 15 decimal digits of precision, although a maximum of 17 digits is maintained internally. The precision of a floating-point number has several consequences: Two floating-point numbers that appear equal for a particular precision might not compare equal because their least significant digits are different. A mathematical or comparison operation that uses a floating-point number might not yield the same result if a decimal number is used because the floating-point number might not exactly approximate the decimal number. A value might not roundtrip if a floating-point number is involved. A value is said to roundtrip if an operation converts an original floating-point number to another form, an inverse operation transforms the converted form back to a floating-point number, and the final floating-point number is equal to the original floating-point number. The roundtrip might fail because one or more least significant digits are lost or changed in a conversion.
Use decimal instead of double and everything will be OK:
decimal Num = 6578336356630531.0m;
string StringNum = Num.ToString("000.0");
The problem is connected with double values representation and precision.
double cannot store that amount of precision. Use a decimal if that's the behaviour you want.
It would seem you have found a number that cannot be represented by a floating-point numkber correctly.
try using a decimal instead:
decimal Num = 6578336356630531.0m;
string StringNum = Num.ToString("###.0");
Maximal whole number without rounding in double precision is 2^53 - 1, which is approx 9e15, but you have 6e15, which may possibly be represented preciously, but not necessarily. You had a bad luck (quite often type of bad luck; deal with it). If you want to live without these surprises, you have to use decimal type in c#.