需要帮助理解C#浮点字符串格式

时间:2016-11-08 18:57:58

标签: c#

简而言之,我想知道为什么下面的ToString()行不符合我的期望。

float actual = 111253.469F;
double rounded = Math.Round(actual, 2); //  111253.47 (expected)
string stringified = actual.ToString(); //  111253.50 (expected 111253.469)
string currency = actual.ToString("C"); // $111253.50 (expected 111253.47 or possibly .46)

有人可以解释发生了什么吗?

注意: 根据浮点数的其他问题,我不认为浮点值是精确的。但是我确实希望字符串输出反映有问题的浮点数的字符串值。

在这种情况下,如果我设置一个断点并在快速监视中查看“实际”的值,它不会显示“111253.5”,它会显示“111253.469”。我不明白为什么打印时不会出现这种情况。特别是在货币情况下,我希望它能够舍入到适当的小数点然后显示,而不是选择其他一些字面值。这不是一个数学问题,它是一个ToString()行为问题。

编辑: 根据下面的每个Quantic的评论,ToString默认使用G格式,将数字限制为7位有效数字,从而导致数字在此处显示。

2 个答案:

答案 0 :(得分:1)

根据MSDN about Single.ToString()(强调我的):

  

默认情况下,返回值仅包含7位精度,但内部最多保留9位数。如果此实例的值大于7位,则M:System.Single.ToString(System.String)返回P:System.Globalization.NumberFormatInfo.PositiveInfinitySymbol或P:System.Globalization.NumberFormatInfo.NegativeInfinitySymbol而不是预期的数字。 如果您需要更高的精度,请指定格式为“G9”格式规范(始终返回9位精度)或“R”,如果数字可以用该精度表示,则返回7位数,如果是,则返回9位数数字只能以最大精度表示

因此,您的代码示例的行为完全符合记录:

    默认情况下,
  • ToString()将使用"G",这将使用7位精度
  • ToString("C")也将使用7位精度

"R""G9"都会返回111253.469"G8"会返回111253.47

答案 1 :(得分:0)

您没有 ToString()问题,您有浮动问题。

float是一个浮点值,根据定义,它具有7位数的精度:MSDN

现在,您有超过7个数字:float actual = 111253.469F,因此系统会对最不重要的数字进行舍入,并且您的操作会获得 111253.5 。 请注意, double 是正确计算的,因为它可以处理超过7位有效数字。