有没有一种简单、高效且正确的方法(即不涉及转换为/从double)在C#中执行向下取整整数除法(例如,类似于Python提供的{{link1:链接}})。
换句话说,以下是一个高效的版本,它不会遭受长/双精度转换损失。
(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;
}
*) 尽管 C# 4 规范在除法运算符上 未明确说明 是否在 unchecked
内引发 OverflowException
,但实际上它确实会引发(在我的系统上),而且 Visual Studio .NET 2003 版本 甚至强制要求它引发:
如果左操作数是最小的可表示 int 或 long 值,右操作数为 -1,则无论该操作是否发生在 checked 或 unchecked 上下文中,都会在此情况下始终引发 System.OverflowException。
编辑
关于 checked
和 unchecked
的划掉语句都很好,但实际上 checked
只是一个编译时概念,所以无论调用函数的代码是否在 checked
中,我的函数是否应该包装或抛出异常都取决于我。
Math.Floor
函数? - Pierre-Luc Pineault/
运算符实现不同。 - Peter Dunihovar a = long.MinValue; var b = -1L;
或var a = long.MaxValue; var b = -1L;
。 - publicgk