[Python-Dev] Memory size overflows

Gerald S. Williams gsw@agere.com
Wed, 16 Oct 2002 12:00:06 -0400


Jeff Epler wrote:
> Is this correct for all operands?  Consider 4-bit types, with valid
> values 0..15.
>     3*9 == 27, but 27%16 == 11 and 11>max(3, 9)

You're right. It's a case of "fingers quicker than the
brain". There may be something worth investigating in
that type of relationship, but that isn't the answer.
I came up with it as I was responding with a somewhat
more working answer.

What I was originally going to post before my mental
lapse was this:

One solution to what Guido asked for is as follows. It
avoids the division, but I don't think it's worth it
(it doesn't make much difference on my platform):

#define FULL_BITS (sizeof(size_t) * 8U)
#define TOP_BIT (((size_t)1) << ((FULL_BITS)-1))
#define HALF_BITS (sizeof(size_t) * 4U)
#define LO_MASK ((((size_t)1) << (HALF_BITS))-1)
#define HI_MASK (~(LO_MASK))

#define SAFE_MULTIPLY(dest,src1,src2,on_error)\
    {\
        size_t _x = src1;\
        size_t _y = src2;\
        \
        dest = _x * _y;\
        \
        if ((_x|_y) & HI_MASK)\
        {\
            size_t h;\
            size_t l;\
            size_t mask;\
            size_t low_bit;\
            size_t low_bit_mask;\
            \
            if (_x >= _y)\
            {\
                h = _x;\
                l = _y;\
            }\
            else\
            {\
                h = _y;\
                l = _x;\
            }\
            \
            for (low_bit=0,mask=TOP_BIT; mask & HI_MASK; ++low_bit,(mask>>=1))\
            {\
                if (h & mask)\
                {\
                    break;\
                }\
            }\
            \
            low_bit_mask = (size_t)1 << low_bit;\
            \
            do\
            {\
                if (l & mask)\
                {\
                    on_error;\
                }\
                mask >>= 1;\
            }\
            while (!(mask & low_bit_mask));\
        }\
    }

Well, at least it demonstrates how to avoid multiply-invoking
its parameters. :-)

-Jerry