开发者

.NET's ToString() Number Truncating

开发者 https://www.devze.com 2023-02-04 09:48 出处:网络
So, WPF calls ToString() on objects when generating TextColumns in DataGrid and then i found out strange thing about ToString() method:

So, WPF calls ToString() on objects when generating TextColumns in DataGrid and then i found out strange thing about ToString() method: Check this ou开发者_运维百科t :

object a = 0.3780000001;//Something like this
Console.WriteLine(a.ToString());//Gets truncated in some cases

First, I thought it was just rounding, but few times I was able to reproduce such behavior on doubles with < 15 digits after dot. Am I missing something?


To the computer, 0.378 and 0.378000...0001 are the same number. See this question: Why is floating point arithmetic in C# imprecise?


As defined on the MSDN page for System.Double, the double type only contains a maximum of fifteen digits of precision. Even though it maintains 17 internally, your figure contains 18 significant digits; this is outside the range of System.Double.


Use decimal instead of float for a more precise type.


By default, Double.ToString() truncates to 15 digits after the dot, but if you really want to use the double data type and you need those 2 extra digits, you can use th "G17" formatting string:

double x = 3.1415926535897932;

string pi = x.ToString("G17");

This will give you a string with the full 17 digits.


I wouldn't assume (so fast) that you found a bug in something as crucial as C#'s ToString implementation.

The behaviour you're experiencing is caused by the fact that a float is imprecisely stored in computer memory (also see this question).


maybe the number format's accuracy range doesn't contain that number? (ie, float only has accuracy to a few significant figures)


If you're data-binding the value, you can supply a ValueConverter which formats the number any way you want.

http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx


Set a to be an Decimal and it will print it correctly!

decimal a = 0.378000000000000001m;
    Console.WriteLine(a.ToString()); 


You could have a common decimal format setting to use all the time.

eg


 object a = 0.378000000000000001;
 Console.WriteLine(a.ToString(Settings.DecimalFormat));
0

精彩评论

暂无评论...
验证码 换一张
取 消