为什么模数运算符在c#中不能用于double?

11 .net c#

考虑一下:

double x,y;
x =120.0;
y = 0.05;

double z= x % y;
Run Code Online (Sandbox Code Playgroud)

我试过这个,并期望结果为0,但它出来了0.04933333.

然而,

x =120.0;
y = 0.5;
double z= x % y;
Run Code Online (Sandbox Code Playgroud)

确实给出了0的正确结果.

这里发生了什么?

我试过Math.IEEERemainder(double, double)但它也没有返回0.这里发生了什么?

另外,另外,在C#中找到余数最合适的方法是什么?

Ste*_*ger 15

由于其存储格式,doubles无法完全按照输入或显示的方式存储每个值.数字的人类表示通常是十进制格式,而doubles基于双系统.

在a中double,120精确存储是因为它是一个整数值.但0.05事实并非如此.双精度近似于0.05它可以表示的最接近的数字.0.52(1/2)的幂,所以它可以精确存储,你不会得到舍入误差.

要使所有数字与在十进制系统中输入/显示它的方式完全相同,请decimal改用.

decimal x, y;
x = 120.0M;
y = 0.05M;

decimal z = x % y;  // z is 0
Run Code Online (Sandbox Code Playgroud)

  • "可能略有不同的确切值"==不准确. (3认同)
  • @chux:每个数字值都有其分辨率。在此上下文中,“精确”表示该值完全按照您 ** 输入** 或 ** 显示** 的方式存储。整数是精确值。如果您输入 7(例如在代码中输入一个常量),它不会在幕后存储 6.999999999999999。对于小数也是如此。双打不一样。由于其存储格式,它无法在输入/显示值时准确存储值。 (2认同)
  • @Bathsheba:实现 IEEE754 无助于使 double 精确存储十进制值。请参阅我关于输入/显示值(使用十进制系统)和双精度存储格式之间差异的最后评论。如果您不相信我所说的,请使用问题中的代码自行复制。 (2认同)

Kev*_*ngs 10

你可以这样做:

double a, b, r;

a = 120;
b = .05;

r = a - Math.floor(a / b) * b;
Run Code Online (Sandbox Code Playgroud)

这应该有帮助;)