简体   繁体   English

C# Math.Round 模棱两可的问题

[英]C# Math.Round ambiguous issue

a,b are of type long a,b 是long类型

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

The call is ambiguous between the following methods or properties: System.Math.Round(double, int) and System.Math.Round(double, System.MidpointRounding)以下方法或属性之间的调用不明确: System.Math.Round(double, int)System.Math.Round(double, System.MidpointRounding)

How to tell compiler that second argument is int and not System.MidpointRounding ?如何告诉编译器第二个参数是int而不是System.MidpointRounding

Edit 1: For some reason, if I run above code stand-alone, I get the error " Error CS0121 The call is ambiguous between the following methods or properties: 'Math.Round(double, int)' and 'Math.Round(decimal, int)' " but my original code runs as part of long script where a, b are implictly-typed intermediate variables and gives me above confusing error message.编辑 1:出于某种原因,如果我单独运行上面的代码,我会收到错误消息“ Error CS0121 The call is ambiguous between the following methods or properties: 'Math.Round(double, int)' and 'Math.Round(decimal, int)' " 但我的原始代码作为长脚本的一部分运行,其中 a、b 是隐式类型的中间变量,并给我上面令人困惑的错误消息。

There are two right answers:有两个正确答案:

  1. Use named parameter ie Math.Round(a/b, digits: 2) [thanks to colinB's comment]使用命名参数即Math.Round(a/b, digits: 2) [感谢 colinB 的评论]
  2. Cast to double (although this is not obvious from original error message) ie Math.Round((double)a/b, 2) [thanks to Owen Pauling's answer]强制转换为 double(尽管这从原始错误消息中并不明显)即Math.Round((double)a/b, 2) [感谢 Owen Pauling 的回答]

There's a couple of things wrong with your question.你的问题有几个问题。 Before the edit, it showed two properties being divided to produce the first argument to Math.Round .在编辑之前,它显示了两个属性被划分为Math.Round的第一个参数。 I expect these values are integers, and therefore your result is not a double, but an integer.我希望这些值是整数,因此您的结果不是双精度值,而是整数。 An integer can be implicitly cast to a double or a decimal.整数可以隐式转换为双精度或小数。 This leads to the second problem with the question, which is that the overload that is ambiguous is System.Math.Round( decimal , System.MidpointRounding).这就引出了问题的第二个问题,就是有歧义的重载是System.Math.Round( decimal ,System.MidpointRounding)。 Basically, the compiler doesn't know if you're calling the overload with the double or the decimal.基本上,编译器不知道你是用双精度还是小数调用重载。

You can fix this by making sure the result of the division is a double, eg:您可以通过确保除法的结果是双精度来解决此问题,例如:

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

Owen Pauling briefly touched upon this problem, but I feel it needs a bit more attention for future readers: Owen Pauling 简要地谈到了这个问题,但我觉得未来的读者需要多加注意:

When both a and b are integer types (long in your case) then the result of the division itself is already an integer (implicitly rounded towards zero).当 a 和 b 都是整数类型(在您的情况下为 long )时,除法本身的结果已经是一个整数(隐式舍入为零)。 This happens already before the call to Math.Round, which is too early to accomplish what you seem to want here.这已经发生在调用 Math.Round 之前,这对于完成您在这里似乎想要的还为时过早。

So basically you are asking to round an integer to an integer, which of course does not make sense.所以基本上你要求将一个整数四舍五入为一个整数,这当然没有意义。 This is why there is no Math.Round expecting integer typed numbers, which is why it requires casting and does not know what to cast it to.这就是为什么没有 Math.Round 期望整数类型的数字,这就是为什么它需要转换并且不知道将其转换为什么。

To summarize: This looks like a common bug.总结一下:这看起来像是一个常见的错误。 You are not asking for what you think you are asking for, and the rounding will not behave as you want it to, unless you cast to your chosen non-integer type before dividing, like this:你不是在要求你认为你在要求的东西,并且舍入不会像你想要的那样表现,除非你在划分之前转换为你选择的非整数类型,如下所示:

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

But do not merely circumvent the compilation error like this:但不要仅仅像这样规避编译错误:

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

(Note: Because casting has a higher priority than division, it does not matter whether you cast the dividend or the divisor. I prefer casting the divisor because it makes it visually obvious that the casting is performed before the division.) (注意:因为转换的优先级高于除法,所以转换被除数还是除数都没有关系。我更喜欢转换除数,因为它在视觉上明显地表明转换是在除法之前执行的。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM