C#中“%”操作对数字类型double的含义

最近我发现C#的运算符%适用于double。 尝试了一些事情,毕竟想出了这个测试:

 class Program { static void test(double a, double b) { if (a % b != a - b * Math.Truncate(a / b)) { Console.WriteLine(a + ", " + b); } } static void Main(string[] args) { test(2.5, 7); test(-6.7, -3); test(8.7, 4); //... } } 

这个测试中的一切都有效。 a % b总是等于a - b*Math.Round(a/b) ? 如果没有,请向我解释这个运营商是如何运作的。

编辑:回答詹姆斯L, 我明白这是一个模数运算符和一切。 我很好奇它是如何使用双重的 ,我理解的整数。

模数运算符以与整数相同的方式处理浮点值。 所以考虑一个简单的例子:

 4.5 % 2.1 

现在,4.5 / 2.1约等于2.142857

因此,除法的整数部分是2.从4.5减去2 * 2.1,你有剩余的0.3。

当然,这个过程受浮点表示问题的影响所以要小心 – 你可能会看到意想不到的结果。 例如,在Stack Overflow上看到这个问题: 浮点运算 – 双类型上的模运算符


%b是否总是等于a – b * Math.Round(a / b)?

不它不是。 这是一个简单的反例:

 static double f(double a, double b) { return a - b * Math.Round(a / b); } static void Main(string[] args) { Console.WriteLine(1.9 % 1.0); Console.WriteLine(f(1.9, 1.0)); Console.ReadLine(); } 

至于如何指定模数运算符的精确细节,你需要参考C#规范 – earlNameless的答案为你提供了一个链接。

我的理解是, a % b基本等效,模浮点精度为a - b*Math.Truncate(a/b)

从C#语言规范页面200:

浮点余数:

 float operator %(float x, float y); double operator %(double x, double y); 

下表列出了非零有限值,零,无穷大和NaN的所有可能组合的结果。 在表中,x和y是正有限值。 z是x%y的结果,计算为x – n * y,四舍五入到最接近的可表示值,其中n是小于或等于x / y的最大整数。 这种计算余数的方法类似于用于整数操作数的方法,但不同于IEC 60559定义(其中n是最接近x / y的整数)。

从MSDN页面 :

模数运算符(%)在将第一个操作数除以第二个操作数后计算余数。 所有数字类型都有预定义模数运算符

请注意与double类型相关的舍入错误。