同时划分并获得剩余?

Ben*_*Ben 44 x86 modulo divide

显然,x86(可能还有很多其他指令集)将除法运算的商和余数都放在不同的寄存器中.

现在,我们可以信任编译器来优化这样的代码,只使用一次调用来划分:

( x / 6 )
( x % 6 )
Run Code Online (Sandbox Code Playgroud)

他们可能会这样做.仍然,任何语言(或图书馆,但主要是寻找语言)支持同时给出除法和模数结果吗?如果是这样,它们是什么,语法是什么样的?

bta*_*bta 46

C有divldiv.这些是否为商和余数生成单独的指令将取决于您的特定标准库实现以及编译器和优化设置.从C99开始,你也有lldiv更大的数字.

  • 令人惊讶的是,为什么不接受这个答案 - 它完全符合要求. (7认同)
  • **不要将它与当前的编译器一起使用,特别是对于除以常数的除法:它不优化**.请参阅https://godbolt.org/g/ydL27q:`div(var,10)`编译成实际的函数调用,而`div`库实现没有divisor是常量`10的信息. .所以它不能使用[乘法逆](/sf/ask/2882875481/) .即使使用运行时变量除数,您也可以在x86上获得更大的代码大小和非内联函数调用. (3认同)

Elo*_*off 31

Python确实如此.

>>> divmod(9, 4)
(2, 1)
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为Python是如此高级的语言.

Ruby也是如此:

11.divmod(3) #=> [3, 2]
Run Code Online (Sandbox Code Playgroud)

*编辑*

应该注意的是,这些操作符的目的可能不是尽可能有效地完成工作,更有可能出于正确性/可移植性原因存在这些功能.

对于那些感兴趣的人,我相信这是整数divmod的Python实现代码:

static enum divmod_result
i_divmod(register long x, register long y,
     long *p_xdivy, long *p_xmody)
{
long xdivy, xmody;

if (y == 0) {
    PyErr_SetString(PyExc_ZeroDivisionError,
                    "integer division or modulo by zero");
    return DIVMOD_ERROR;
}
/* (-sys.maxint-1)/-1 is the only overflow case. */
if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x))
    return DIVMOD_OVERFLOW;
xdivy = x / y;
/* xdiv*y can overflow on platforms where x/y gives floor(x/y)
 * for x and y with differing signs. (This is unusual
 * behaviour, and C99 prohibits it, but it's allowed by C89;
 * for an example of overflow, take x = LONG_MIN, y = 5 or x =
 * LONG_MAX, y = -5.)  However, x - xdivy*y is always
 * representable as a long, since it lies strictly between
 * -abs(y) and abs(y).  We add casts to avoid intermediate
 * overflow.
 */
xmody = (long)(x - (unsigned long)xdivy * y);
/* If the signs of x and y differ, and the remainder is non-0,
 * C89 doesn't define whether xdivy is now the floor or the
 * ceiling of the infinitely precise quotient.  We want the floor,
 * and we have it iff the remainder's sign matches y's.
 */
if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
    xmody += y;
    --xdivy;
    assert(xmody && ((y ^ xmody) >= 0));
}
*p_xdivy = xdivy;
*p_xmody = xmody;
return DIVMOD_OK;
}
Run Code Online (Sandbox Code Playgroud)


Str*_*ger 10

在C#/ .NET中你有Math.DivRem:http: //msdn.microsoft.com/en-us/library/system.math.divrem.aspx

但根据这个线程,这并不是一个优化.