C# Math.Round 歧义问题



a,b 属于long

Math.Round(a/b, (int)2) 

以下方法或属性之间的调用不明确:System.Math.Round(double, int)System.Math.Round(double, System.MidpointRounding)

如何告诉编译器第二个参数是int而不是System.MidpointRounding

编辑1:由于某种原因,如果我独立运行上面的代码,我会收到错误 "Error CS0121 The call is ambiguous between the following methods or properties: 'Math.Round(double, int)' and 'Math.Round(decimal, int)'"但是我的原始代码作为长脚本的一部分运行,其中 a、b 是隐式类型的中间变量,并给了我上面令人困惑的错误消息。

有两个正确答案:

  1. 使用命名参数,即Math.Round(a/b, digits: 2)[感谢colinB的评论]
  2. 转换为双倍(尽管这在原始错误中并不明显 消息),即Math.Round((double)a/b, 2)[感谢欧文·鲍林的回答]

你的问题有几个问题。在编辑之前,它显示了两个属性被分割以产生第一个参数Math.Round。我希望这些值是整数,因此您的结果不是双精度数,而是整数。整数可以隐式转换为双精度或小数。这就引出了问题的第二个问题,即模棱两可的重载是System.Math.Round(十进制,System.MidpointRounding)。基本上,编译器不知道您是用双精度还是小数调用重载。

您可以通过确保除法的结果是双精度来解决此问题,例如:

Math.Round(val1/(double)val2, 2);

> Owen Pauling简要地谈到了这个问题,但我觉得未来的读者需要更多关注:

当 a 和 b 都是整数类型(在您的情况下为 long)时,除法本身的结果已经是一个整数(隐式舍入为零)。这在调用Math.Round之前就已经发生了,这还为时过早,无法实现您在这里想要的东西。

所以基本上你要求将整数四舍五入为整数,这当然没有意义。这就是为什么没有 Math.Round 期待整数类型数字的原因,这就是为什么它需要强制转换并且不知道将其转换为什么。

总结一下:这看起来像一个常见的错误。您没有要求您认为您要求的内容,并且舍入不会按您想要的方式运行,除非您在除法之前转换为您选择的非整数类型,如下所示:

double correct1 = Math.Round(a / (double)b, 2); // Owen Pauling's answer
decimal correct2 = Math.Round(a / (decimal)b, 2);

但不要像这样仅仅规避编译错误:

double inCorrect1 = Math.Round(a / b, digits: 2); // colinB's answer
decimal inCorrect2 = Math.Round(a / b, decimals: 2);

(注意:因为铸造的优先级高于除法,所以投除数还是除数并不重要。我更喜欢铸造除数,因为它在视觉上很明显,铸造是在除法之前执行的。

最新更新