Divide and Get Remainder at the same time?

后端 未结 9 1133
不知归路
不知归路 2020-12-15 02:37

Apparently, x86 (and probably a lot of other instruction sets) put both the quotient and the remainder of a divide operation in separate registers.

Now, we can proba

9条回答
  •  粉色の甜心
    2020-12-15 03:21

    Python does.

    >>> divmod(9, 4)
    (2, 1)
    

    Which is odd, becuase Python is such a high level language.

    So does Ruby:

    11.divmod(3) #=> [3, 2]
    

    * EDIT *

    It should be noted that the purpose of these operators is probably not to do the work as efficiently as possible, it is more likely the functions exist for correctness/portability reasons.

    For those interested, I believe this is the code of the Python implementation for integer divmod:

    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;
    }
    

提交回复
热议问题