如何在C#中计算整数的除法和取模?


85

如何在C#中计算整数的除法和取模?


15
这可能太基本了,但这是一个真正的问题……

2
有关为什么运算符不是C#中的模数运算符的相关文章和必读博客%
RBT

Answers:


123

在问这种问题之前,请查看MSDN文档

当您将两个整数相除时,结果始终是整数。例如,7/3的结果为2。要确定7/3的余数,请使用余数运算符()。

int a = 5;
int b = 3;

int div = a / b; //quotient is 1
int mod = a % b; //remainder is 2

9
%返回余数,而不是模数(如您所指出的)。它们不会产生相同的结果,并且在处理异常情况(例如,负索引)时可能会引起问题。但是,当仅查找(例如)弱正索引器的第10次迭代时,可以像模运算符一样使用它。也许您可以解释如何计算实际模量?
Cor_Blimey 2012年

1
没错,我读过这样的帖子,而我的应用程序中有问题:)
启示录2013年

1
...声明的确切目的是什么ab如果您不打算使用它们?:D
leviathanbadger 2013年

1
也许用户正在(像我一样)搜索DivRem函数,所以问题可能并不像乍看起来那样琐碎。感谢@danodonovan
Tancredi

1
答案并不像其他人所指出的那样简单,而是可能导致难以调试的错误。参见/programming/10065080/mod-explanation
SansWit

88

也有 Math.DivRem

quotient = Math.DivRem(dividend, divisor, out remainder);

2
我认为这应该是正确的答案,因为它在一个函数中提供了商和余数。我不确定哪种方法效果更好(使用“ a / b”获得商,然后使用“ a%b”获得余数或Math.DivRem),但是这种方法肯定更易于阅读(就我而言,我需要知道商数和余数)-谢谢!
伊戈尔2015年

2
@Igor谢谢,当回答原始问题时,此功能不存在!但是,该函数的存在确实使as-cii的有关检查文档的言论显得有些愚蠢.... :)
danodonovan

5
只是为了避免混淆,Math.DivRem不要在一个操作中计算div和mod。它只是一个辅助函数,其源代码完全是:public static int DivRem(int a, int b, out int result) { result = a%b; return a/b; }
NightElfik '16

9
@NightElfik将来实现可能会发生变化,运行时识别方法优化的调用比不相交divrem指令更容易
kbolino 2016年

6
@kbolino这是一个很好的预测,因为至少在.NET Core中更改为除法和减法。RyuJIT还计划使用单个x86 div指令进行进一步的优化,尽管可以肯定的是%/如果单独使用JIT更改,则还应该检测和运算符。
鲍勃(Bob)

15

有趣的事实!

“取模”操作定义为:

a % n ==> a - (a/n) * n

参考:模块化算术

因此,您可以自己滚动,尽管它的FAR速度比内置的%运算符慢:

public static int Mod(int a, int n)
{
    return a - (int)((double)a / n) * n;
}

编辑:哇,原来这里很不对劲,谢谢@joren抓住了我

现在,在这里我依靠的事实是,C#中的除法+强制转换为int等效于Math.Floor(即,它除去了分数),但是“真正的”实现将是这样的:

public static int Mod(int a, int n)
{
    return a - (int)Math.Floor((double)a / n) * n;
}

实际上,您可以通过以下方法查看%和“真实模量”之间的差异:

var modTest =
    from a in Enumerable.Range(-3, 6)
    from b in Enumerable.Range(-3, 6)
    where b != 0
    let op = (a % b)
    let mod = Mod(a,b)
    let areSame = op == mod
    select new 
    { 
        A = a,
        B = b,
        Operator = op, 
        Mod = mod, 
        Same = areSame
    };
Console.WriteLine("A      B     A%B   Mod(A,B)   Equal?");
Console.WriteLine("-----------------------------------");
foreach (var result in modTest)
{
    Console.WriteLine(
        "{0,-3} | {1,-3} | {2,-5} | {3,-10} | {4,-6}", 
        result.A,
        result.B,
        result.Operator, 
        result.Mod, 
        result.Same);
}

结果:

A      B     A%B   Mod(A,B)   Equal?
-----------------------------------
-3  | -3  | 0     | 0          | True  
-3  | -2  | -1    | -1         | True  
-3  | -1  | 0     | 0          | True  
-3  | 1   | 0     | 0          | True  
-3  | 2   | -1    | 1          | False 
-2  | -3  | -2    | -2         | True  
-2  | -2  | 0     | 0          | True  
-2  | -1  | 0     | 0          | True  
-2  | 1   | 0     | 0          | True  
-2  | 2   | 0     | 0          | True  
-1  | -3  | -1    | -1         | True  
-1  | -2  | -1    | -1         | True  
-1  | -1  | 0     | 0          | True  
-1  | 1   | 0     | 0          | True  
-1  | 2   | -1    | 1          | False 
0   | -3  | 0     | 0          | True  
0   | -2  | 0     | 0          | True  
0   | -1  | 0     | 0          | True  
0   | 1   | 0     | 0          | True  
0   | 2   | 0     | 0          | True  
1   | -3  | 1     | -2         | False 
1   | -2  | 1     | -1         | False 
1   | -1  | 0     | 0          | True  
1   | 1   | 0     | 0          | True  
1   | 2   | 1     | 1          | True  
2   | -3  | 2     | -1         | False 
2   | -2  | 0     | 0          | True  
2   | -1  | 0     | 0          | True  
2   | 1   | 0     | 0          | True  
2   | 2   | 0     | 0          | True  

“现在,我依靠的事实是C#中的整数除法等于Math.Floor(即,它除去了分数)”-但事实并非如此。整数除法四舍五入为零,数学乘数四舍五入为负无穷大。
乔伦(Joren)2013年

@Joren抱歉,但没有-尝试运行此命令:Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));-全0
JerKimball 2013年

2
首先,我说的是整数除法。如果执行浮点除法然后将其强制转换为整数会发生什么无关紧要的(即使得到的结果相同)。其次,我不确定为什么您会期望0到9之间的整数在除以10并截断为整数部分后给出除0以外的任何值。如果这导致1将被舍去远离从零或向无穷大。第三,对零舍入和对正数舍入为负无穷之间没有任何区别,因此您甚至都没有解决这个问题。
2013年

Math.Floor(-10.0 / 3.0)并且-10 / 3一样的东西。
2013年

@joren啊,我在这里看到了断开连接-不,我没有执行整数除法,我正在执行双除法,然后将结果转换为整数-非常不同。
JerKimball

14

使用/运算符执行除法:

result = a / b;

模除法使用%运算符完成:

result = a % b;

1
+1:方便地省略类型使它成为一个更好的答案:-)我相信这也适用于4.0中的System.Numeric.BigInteger。

5
%->如Cor_Blimey所说,它返回余数而不是模数。例如:(-5%3)== -2 [C#],-5 mod 3 = 1 [wolframalpha.com]。
启示

2
注意:Modulo与Modulus不同。模数是余数,模数是绝对值。
瑞安

-4

从用户读取两个整数。然后计算/显示余数和商

// When the larger integer is divided by the smaller integer
Console.WriteLine("Enter integer 1 please :");
double a5 = double.Parse(Console.ReadLine());
Console.WriteLine("Enter integer 2 please :");
double b5 = double.Parse(Console.ReadLine());

double div = a5 / b5;
Console.WriteLine(div);

double mod = a5 % b5;
Console.WriteLine(mod);

Console.ReadLine();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.