为什么模数运算符不适用于 c# 中的 double?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/906564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is modulus operator not working for double in c#?
提问by
Consider this:
考虑一下:
double x,y;
x =120.0;
y = 0.05;
double z= x % y;
I tried this and expected the result to be 0, but it came out 0.04933333.
我试过这个并期望结果为 0,但结果为 0.04933333。
However,
然而,
x =120.0;
y = 0.5;
double z= x % y;
did indeed gave the correct result of 0.
确实给出了正确的结果 0。
What is happening here?
这里发生了什么?
I tried Math.IEEERemainder(double, double)
but it's not returning 0 either. What is going on here?
我试过了,Math.IEEERemainder(double, double)
但它也没有返回 0。这里发生了什么?
Also, as an aside, what is the most appropriate way to find remainder in C#?
另外,顺便说一句,在 C# 中找到余数的最合适方法是什么?
回答by Stefan Steinegger
Because of its storage format, double
s cannot store every values exactly as is is entered or displayed. The human representation of numbers is usually in decimal format, while double
s are based on the dual system.
由于其存储格式,double
s 不能完全按照输入或显示的原样存储每个值。人类对数字的表示通常是十进制格式,而double
s 是基于双系统的。
In a double
, 120
is stored precisely because it's an integer value. But 0.05
is not. The double is approximated to the closest number to 0.05
it can represent. 0.5
is a power of 2
(1/2
), so it can be stored precisely and you don't get a rounding error.
在 a 中double
,120
精确存储,因为它是一个整数值。但0.05
不是。double 近似于0.05
它可以表示的最接近的数字。0.5
是2
( 1/2
)的幂,因此可以精确存储并且不会出现舍入错误。
To have all numbers exactly the same way you enter / display it in the decimal system, use decimal
instead.
要使所有数字以十进制系统输入/显示的方式完全相同,请decimal
改用。
decimal x, y;
x = 120.0M;
y = 0.05M;
decimal z = x % y; // z is 0
回答by Flo
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problemscan help you understand why you get these "strange" results. There's a particular precision that floating point numbers can have. Just try these queries and have a look at the results:
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems可以帮助您理解为什么会得到这些“奇怪”的结果。浮点数可以具有特定的精度。只需尝试这些查询并查看结果:
回答by Kevin Dungs
You could do something like:
你可以这样做:
double a, b, r;
a = 120;
b = .05;
r = a - Math.floor(a / b) * b;
This should help ;)
这应该有帮助;)
回答by rockeye
Modulus should only be used with integer. The remainder come from an euclidean division. With double, you can have unexpected results.
模数只能与整数一起使用。其余部分来自欧几里德除法。使用double,您可以获得意想不到的结果。
See this article
看这篇文章
回答by configurator
I believe if you tried the same with decimal
it would work properly.
我相信如果您尝试相同的方法,decimal
它会正常工作。
回答by Giorgos Pippos
This is what we use.. :)
这就是我们使用的.. :)
public double ModuloOf(double v1, double v2)
{
var mult = 0;
//find number of decimals
while (v2 % 1 > 0)
{
mult++;
v2 = v2 * 10;
}
v1 = v1 * Math.Pow(10, mult);
var rem = v1 % v2;
return rem / Math.Pow(10, mult);
}