奇怪的李XX

Oct 16, 2023

取余与取模

余数运算符 %

余数运算符 % 计算左侧操作数除以右侧操作数后的余数。

整数余数

对于整数类型的操作数,a % b 的结果是 a - (a / b) * b 得出的值。 非零余数的符号与左侧操作数的符号相同

1
2
3
4
Console.WriteLine(5 % 4);   // output: 1
Console.WriteLine(5 % -4); // output: 1
Console.WriteLine(-5 % 4); // output: -1
Console.WriteLine(-5 % -4); // output: -1

浮点余数

对于 float 和 double 操作数,有限的 x 和 y 的 x % y 的结果是值 z,因此

  • z(如果不为零)的符号与 x 的符号相同。
  • z 的绝对值是 |x| - n * |y| 得出的值,其中 n 是小于或等于 |x| / |y| 的最大可能整数,|x| 和 |y| 分别是 x 和 y 的绝对值。
1
2
3
Console.WriteLine(-5.2f % 2.0f); // output: -1.2
Console.WriteLine(5.9 % 3.1); // output: 2.8
Console.WriteLine(5.9m % 3.1m); // output: 2.8

取余运算(Complementation)和取模运算(Modulo Operation)的区别

c++和C#中,运算符‘%’为取余运算符,而并非取模预算符,在一些应用场景中,如果不加以区分,会产生严重的bug。

对于整型数a,b来说,取模运算或取余运算的方法都是:

  • 第一步:求 整数商: c = a/b;
  • 第二步:计算模或者余数: r = a - c*b.

两者的区别在于第一步: 取余运算在取c的值时,向0方向舍入(fix()函数);

取模运算在计算c的值时,向负无穷方向舍入(floor()函数)。

例如:a = -7,b = 4

  • 第一步:求整数商c,求余c = -1(向0方向舍入),求模运算c = -2(向负无穷方向舍入);
  • 第二步:计算模和余数的公式相同,但因c的值不同,求余时r = -3,求模时r = 1.

C#中模运算

1
(Math.Abs(a * b) + a) % b
< NEWER