Why does .Net use a rounding algorithm in String.Format that is inconsistent with the default Math.Round() algorithm?

前端 未结 4 914
夕颜
夕颜 2020-12-29 21:20

I\'ve noticed the following inconsistency in C#/.NET. I was wondering why it is so.

Console.WriteLine(\"{0,-4:#.0} | {1,-4:#.0}\", 1.04, Math.Round(1.04, 1)         


        
相关标签:
4条回答
  • 2020-12-29 21:25

    WriteLine(string, params object[]) calls string.Format and passes in the current CultureInfo, so will use your localized NumberFormatInfo to determine how to write the number. Math.Round does not take culture into account, since you are specifying exactly how you want it to round.

    Hm, after poking around Reflector, maybe not :)

    0 讨论(0)
  • 2020-12-29 21:26

    As a historical note, the original Visual Basic implementation of Format$ also was inconsistent with round-to-even, aka, Banker's Rounding. The original Format$ code was written by Tim Paterson. You might recall that Tim was the author of a little program called QDOS (later known as MS-DOS) that was rather a good seller for a while there.

    Perhaps this is yet another case of 25 years of backwards compatibility.

    0 讨论(0)
  • 2020-12-29 21:40

    Seems this problem is worse than a "simple" inconsistency:

    double dd = 0.034999999999999996;
    
    Math.Round(dd, 2); // 0.03
    Math.Round(dd, 2, MidpointRounding.AwayFromZero); // 0.03
    Math.Round(dd, 2, MidpointRounding.ToEven); // 0.03
    
    string.Format("{0:N2}", dd); // "0.04"
    

    This is absolutely bananas. Who knows where the heck it get "0.04" from.

    0 讨论(0)
  • 2020-12-29 21:46

    Please, take a look here: Possible Bug: Math.Round returning inconsistent results

    WriteLine() simply calls Object.ToString(), which in turn ultimately results in a call to Number.FormatDouble(this, null, NumberFormatInfo.CurrentInfo). As you can see, the parameter for the format string is null. If you want to get the real thing from ToString() you must use System.Diagnostics.Debug.WriteLine(n.ToString("R")).

    "When a Single or Double value is formatted using this specifier, it is first tested using the general format, with 15 digits of precision for a Double and 7 digits of precision for a Single. If the value is successfully parsed back to the same numeric value, it is formatted using the general format specifier. If the value is not successfully parsed back to the same numeric value, it is formatted using 17 digits of precision for a Double and 9 digits of precision for a Single." Standard Numeric Format Strings

    0 讨论(0)
提交回复
热议问题