【发布时间】:2015-01-21 04:31:41
【问题描述】:
在 C# 中是否有一种简单、高效且正确(即不涉及到/从 double 的转换)的方法来进行 整数除法(例如 Python offers)。
换句话说,以下的有效版本,不会遭受长/双转换损失。
(long)(Math.Floor((double) a / b))
或者是否必须自己实现它,例如
static long FlooredIntDiv(long a, long b)
{
if (a < 0)
{
if (b > 0)
return (a - b + 1) / b;
// if (a == long.MinValue && b == -1) // see *) below
// throw new OverflowException();
}
else if (a > 0)
{
if (b < 0)
return (a - b - 1) / b;
}
return a / b;
}
*) 尽管除法运算符 leaves it open 的 C# 4 规范是否在 OverflowException 内部引发了 unchecked,但实际上它确实抛出(在我的系统上)并且 Visual Studio .NET 2003 version 甚至强制它抛出:
如果左操作数是最小的可表示的 int 或 long 值,而右操作数是 –1,则在这种情况下总是抛出 [..] System.OverflowException,无论操作发生在已检查或未检查的上下文中.
编辑
关于checked 和unchecked 的划掉的语句都很好,但是checked 实际上只是一个compile time concept,所以我的函数应该环绕还是抛出不管调用函数的代码是否在checked 中,这都取决于我。
【问题讨论】:
-
您的意思是,将结果传递给
Math.Floor? -
整数除法已经在这样做了,不是字面上调用
Math.Floor,但结果是一样的,它会切断整个小数部分。Math.Floor在这种情况下是多余的。 -
@maremp:仅用于阳性结果。有关与 C#
/运算符实现不同的“地板”否定结果示例,请参阅 OP 的表。 -
哦,是的@PeterDuniho,我忘了...
-
不是解决方案,但我相信您的代码在某些极端情况下可能会失败。
var a = long.MinValue; var b = -1L;或var a = long.MaxValue; var b = -1L;.
标签: c# .net math integer-arithmetic