是否有一种简单,有效和正确的方法(即不涉及到 double 的转换)来在C#中进行底整数除法(例如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;
}

*)尽管Division运算符leaves it open的C#4规范是否在OverflowException中引发了unchecked,但实际上它确实抛出了(在我的系统上),并且Visual Studio .NET 2003 version甚至强制它抛出了:



编辑

关于checkedunchecked的划线语句都很好,但是 checked实际上仅是compile time concept ,所以无论如何,我的函数应该环绕还是抛出都取决于我,无论调用该函数的代码是否在checked内部或不。

最佳答案

您可以尝试以下方法:

if (((a < 0) ^ (b < 0)) && (a % b != 0))
{
   return (a/b - 1);
}
else
{
   return (a/b);
}

编辑(在下面的评论中进行了一些讨论之后):

在不使用if-else的情况下,我会这样:
return (a/b - Convert.ToInt32(((a < 0) ^ (b < 0)) && (a % b != 0)));

注意:Convert.ToIn32(bool value)也需要跳转,请参见implemention方法:
return value? Boolean.True: Boolean.False;

从理论上讲,不可能计算a = long.MinValueb = -1L的除法,因为期望的结果是a/b = abs(long.MinValue) = long.MaxValue + 1 > long.MaxValue。 (long的范围是–9,223,372,036,854,775,8089,223,372,036,854,775,807。)

关于c# - 地板整数除法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28059655/

10-13 07:46
查看更多