为什么模数运算符不适用于 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 02:31:45  来源:igfitidea点击:

Why is modulus operator not working for double in c#?

c#.net

提问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, doubles cannot store every values exactly as is is entered or displayed. The human representation of numbers is usually in decimal format, while doubles are based on the dual system.

由于其存储格式,doubles 不能完全按照输入或显示的原样存储每个值。人类对数字的表示通常是十进制格式,而doubles 是基于双系统的。

In a double, 120is stored precisely because it's an integer value. But 0.05is not. The double is approximated to the closest number to 0.05it can represent. 0.5is a power of 2(1/2), so it can be stored precisely and you don't get a rounding error.

在 a 中double120精确存储,因为它是一个整数值。但0.05不是。double 近似于0.05它可以表示的最接近的数字。0.52( 1/2)的幂,因此可以精确存储并且不会出现舍入错误。

To have all numbers exactly the same way you enter / display it in the decimal system, use decimalinstead.

要使所有数字以十进制系统输入/显示的方式完全相同,请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可以帮助您理解为什么会得到这些“奇怪”的结果。浮点数可以具有特定的精度。只需尝试这些查询并查看结果:

0.5 in base 2

0.5 以 2 为基数

0.05 in base 2

0.05 以 2 为底

回答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 decimalit 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);
    }