Math.Round与String.Format的区别

6

我需要将双精度值四舍五入到2位小数。

哪种方式更好呢?

String.Format("{0:0.00}", 123.4567);      // "123.46"
Math.Round(123.4567, 2)                   // "123.46"

它们不需要相同,因此您可以选择使用 Math.Round 并使用其舍入选项。另外,请查看此字符串格式化舍入 - V4Vendetta
如果您将货币存储为double类型,那么您应该真正考虑使用decimal类型。http://msdn.microsoft.com/en-us/library/364x0z75%28v=vs.80%29.aspx - spender
4
Math.Round(double, digits) 当digits>0时,概念上非常不干净。我认为它不应该被使用。double是一个二进制浮点数,因此没有明确定义的十进制数字的概念。如果需要将数字四舍五入到特定数量的小数位数,请使用Decimal而不是Double - CodesInChaos
1
请注意,第一个使用“远离零”舍入,而第二个使用“四舍五入到偶数”。第二个允许您通过重载指定舍入类型,但默认情况下为“四舍五入到偶数”。 - Matthijs Wessels
6个回答

18

Math.Round(double, digits) 的概念在理论上非常不清晰。但我认为它应该永远不会被使用。因为 double 是一个二进制浮点数,因此没有明确定义的小数位的概念。

我建议在仅需要进行小数位显示舍入时使用 string.Format 或者 ToString("0.00"),并且如果需要对实际数字进行舍入(例如在进一步计算中使用)则使用 decimal.Round

注意:使用 decimal.Round 可以指定一个MidpointRounding模式。通常希望使用 AwayFromZero 舍入方式而不是使用 ToEven(四舍五入)方式。

使用 ToEven 舍入方式时,0.005m 舍入为 0.000.015 舍入为 0.02。这不是大多数人所期望的。

比较:

  • 使用 ToEven 方式:3.75 舍入为 3.8
  • 使用 ToEven 方式:3.85 舍入为 3.8(这不是大多数人所期望的)
  • 使用 AwayFromZero 方式:3.75 舍入为 3.8
  • 使用 AwayFromZero 方式:3.85 舍入为 3.9

更多信息请参见:https://msdn.microsoft.com/en-us/library/system.math.round.aspx


1
如果我不是“大多数人”,该怎么办? - Andriy K
我可能错了,但我认为@CodesInChaos并不是说人们从来没有期望.5向下舍入,他们只是期望它始终如一地舍入(即如果3.75向上舍入,则3.85应该表现类似)。 - Landerah
@AndriyK,您是建议将MidpointRounding保留为ToEven吗?我不确定您的意思。 - Ruben9922
@Ruben9922,我的观点是,当你遵循ToString或string.Format时,你没有这个选项,它总是四舍五入,正如“大多数人所期望的”。 - Andriy K

7

它们是不同的函数,如果需要显示输出,请使用第一个函数(它也会强制小数点出现)。这样可以避免变量为double类型时必然发生的.ToString()开销。

请注意,第二个函数会四舍五入数字,但如果结果是整数,则只会得到整数(例如:7 vs 7.00)


4
这取决于您希望对其进行什么操作。 String.Format 将返回一个字符串,Math.Round(double) 将返回一个双精度浮点数。

1

前者输出一个字符串,后者输出一个双精度浮点数。你对结果的使用是什么?这个问题的答案将决定你的问题的答案。


1

如果你希望将这个值作为一个 string 返回,那么使用 String.Format 更好;如果你希望将这个值作为一个 double 返回,那么使用 Math.Round 更好。完全取决于你的需要。


0

Math.Round如果没有小数位,就不会添加任何小数位。而String.Format则会。 例如:Math.Round(2)返回2; String.Format("{0:0.00}",2)返回2.00;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接