如何在 C# 中计算整数的除法和模数?
Posted
技术标签:
【中文标题】如何在 C# 中计算整数的除法和模数?【英文标题】:How can I calculate divide and modulo for integers in C#? 【发布时间】:2011-07-19 23:26:03 【问题描述】:【问题讨论】:
这可能太基本了,但这是一个真正的问题...... 一个相关的post 和必读的blog 说明为什么%
运算符不是 C# 中的模运算符。
【参考方案1】:
这是来自MSDN documentation的答案。
当你将两个整数相除时,结果总是一个整数。例如,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
【讨论】:
% 返回余数,而不是模数(正如您指出的那样)。它们不是同一件事,并且在处理异常情况(例如负索引)时可能会导致问题。但是,它可以像模运算符一样在仅查找时使用,例如,弱正索引器的每 10 次迭代。或许你能解释一下如何计算真正的模数? 没错,我读过这样的帖子,但我的应用程序有问题:) ...如果您不打算使用它们,那么声明a
和b
到底有什么意义? :D
也许用户(像我一样)正在搜索 DivRem 函数,所以这个问题可能不像乍一看那么简单。谢谢@danodonovan
答案并不像其他人所指出的那样简单,并且可能导致难以调试的错误。见https://***.com/questions/10065080/mod-explanation【参考方案2】:
还有Math.DivRem
quotient = Math.DivRem(dividend, divisor, out remainder);
【讨论】:
在我看来这应该是正确的答案,因为它在一个函数中提供了商和余数。我不确定哪种方法性能更好(使用“a / b”来获得商,然后使用“a % b”来获得余数或 Math.DivRem),但这种方法肯定更好读(在我的情况下,我需要知道商和余数)-谢谢! @Igor 谢谢,回答原始问题时,此功能不存在!然而,该函数的存在确实让 as-cii 关于检查文档的评论看起来有点傻...... :) 为了避免混淆,Math.DivRem
不会一次计算 div 和 mod。它只是一个辅助函数,它的源代码是:public static int DivRem(int a, int b, out int result) result = a%b; return a/b;
。
@NightElfik 未来的实现可能会发生变化,运行时更容易识别方法调用以进行优化,而不是不相交的div
和rem
指令
@kbolino 这是一个很好的预测,因为it has changed 至少在 .NET Core 中可以进行除法运算。 RyuJIT 计划进一步优化以使用单个 x86 div 指令,但诚然,如果单独使用 JIT 更改也应该检测到 %
和 /
运算符。【参考方案3】:
有趣的事实!
“模数”运算定义为:
a % n ==> a - (a/n) * n
参考:Modular Arithmetic
所以你可以自己滚动,虽然它会比内置的 % 运算符慢得多:
public static int Mod(int a, int n)
return a - (int)((double)a / n) * n;
编辑:哇,原来这里说错了,感谢@joren 抓住我
现在,我依赖于 C# 中的除法 + 强制转换为整数等价于 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 的事实(即,它会丢弃分数)” - 但事实并非如此。整数除法向零舍入,Math.Floor 向负无穷舍入。 @Joren 抱歉,不行 - 尝试运行这个:Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));
- 全为 0
首先,我说的是整数除法。如果您进行浮点除法然后转换为整数会发生什么是无关紧要的(即使它给出相同的结果)。其次,我不确定为什么你会期望 0 到 9 之间的整数在除以 10 并截断为整数部分后给出除 0 以外的任何值。如果结果为 1,则将 远离 从零或向 正 无穷大舍入。第三,对于正数,向零四舍五入和向负无穷大四舍五入之间没有任何区别,因此您甚至没有解决这个问题。
Math.Floor(-10.0 / 3.0)
和 -10 / 3
不是相同的东西。
@joren 啊,我看到这里断开连接 - 不,我没有执行 integer 除法,我正在执行双除法,然后将结果转换为整数 - 非常不同。【参考方案4】:
使用/
运算符执行除法:
result = a / b;
使用%
运算符完成模除:
result = a % b;
【讨论】:
+1:方便地省略类型使其成为更好的答案 :-) 我相信这也适用于 4.0 中的 System.Numeric.BigInteger。 % --> 正如 Cor_Blimey 所说,它返回余数而不是模数。例如:(-5 % 3) == -2 [C#], -5 mod 3 = 1 [wolframalpha.com]。 注意:模数与模数不同。模数是余数,模数是绝对值。【参考方案5】:从用户那里读取两个整数。然后计算/显示余数和商,
// 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();
【讨论】:
以上是关于如何在 C# 中计算整数的除法和模数?的主要内容,如果未能解决你的问题,请参考以下文章