如何计算整数的除法和模数?

kar*_*tal 79 c#

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

as-*_*cii 116

在提出此类问题之前,请查看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
Run Code Online (Sandbox Code Playgroud)

  • %返回余数,而不是模数(正如您指出的那样).它们不是同一个东西,在处理异常情况时可能会导致问题(例如负面索引).然而,当仅查找例如弱正分度器的每第10次迭代时,它可以像模数运算符一样使用.也许您可以解释如何计算实际模数? (8认同)

dan*_*van 74

还有 Math.DivRem

quotient = Math.DivRem(dividend, divisor, out remainder);
Run Code Online (Sandbox Code Playgroud)

  • @NightElfik实现可能在将来发生变化,运行时更容易识别优化的方法调用而不是不相交的`div`和`rem`指令 (8认同)
  • 为了避免混淆,`Math.DivRem`不会在一次操作中计算div和mod.它只是一个辅助函数,它的源代码完全是:`public static int DivRem(int a,int b,out int result){result = a%b; 返回a/b; }`. (5认同)
  • @kbolino这是一个很好的预测,因为[它已经*已经改变](http://stackoverflow.com/a/41805430/1030702),至少在.NET Core中,可以进行分割和减法.并且在RyuJIT中计划使用单个x86 div指令进一步优化,但不可否认的是,如果单独使用,JIT更改还应检测`%`和`/`运算符. (4认同)
  • 我认为这应该是正确的答案,因为它在一个函数中提供了商和余数。我不确定哪种方法效果更好(使用“ a / b”获得商,然后使用“ a%b”获得余数或Math.DivRem),但是这种方法肯定更易于阅读(就我而言,我需要知道商数和余数)-谢谢! (2认同)
  • @Igor 谢谢,当回答原始问题时,此功能不存在!但是,该函数的存在确实使 as-cii 关于检查文档的评论看起来有点傻...... :) (2认同)

Rio*_*ams 14

使用/运营商执行分部:

result = a / b;
Run Code Online (Sandbox Code Playgroud)

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

result = a % b;
Run Code Online (Sandbox Code Playgroud)

  • % - >正如Cor_Blimey所说,它返回的余数不是模数.例如:( - 5%3)== -2 [C#], - 5 mod 3 = 1 [wolframalpha.com]. (5认同)
  • 注意:模数与模数不同。Modulo 是余数,Modulus 是绝对值。 (2认同)

Jer*_*all 14

有趣的事实!

'模数'操作定义为:

a % n ==> a - (a/n) * n
Run Code Online (Sandbox Code Playgroud)

参考:模块化算术

所以你可以自己动手,虽然它比内置%运算符慢FAR:

public static int Mod(int a, int n)
{
    return a - (int)((double)a / n) * n;
}
Run Code Online (Sandbox Code Playgroud)

编辑:哇,最初在这里发生了相当严重的错误,感谢@joren抓住了我

现在我在这里依赖的事实是C#中的division + cast-to-int相当于Math.Floor(即,它会丢弃分数),但是"真正的"实现将改为:

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

实际上,您可以通过以下方式查看%和"true modulus"之间的差异:

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);
}
Run Code Online (Sandbox Code Playgroud)

结果:

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  
Run Code Online (Sandbox Code Playgroud)

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