[Python-Dev] Memory size overflows
Gerald S. Williams
gsw@agere.com
Thu, 17 Oct 2002 00:36:23 -0400
I felt obliged to post a working copy of SAFE_MULTIPLY. On
my platform, it's slower than simply dividing by one of the
multiplicands and comparing to the other, but it does get
the job done without division. This is what I started out
to write before my brain short-circuited.
Here's a simplified Python representation of the algorithm:
def check(x,y,m):
xrem, xlog = math.frexp(x)
yrem, ylog = math.frexp(y)
if xlog + ylog == m + 1:
return (xrem * yrem >= 0.5)
else:
return xlog + ylog > m + 1
And here it is in C:
#define FULL_BITS (sizeof(size_t) * 8U)
#define TOP_BIT (((size_t)1) << ((FULL_BITS)-1))
#define HALF_BITS (sizeof(size_t) * 4U)
#define SAFE_MULTIPLY(dest,src1,src2,on_overflow)\
{\
size_t _x = src1;\
size_t _y = src2;\
size_t _dest = _x * _y;\
size_t h;\
int hlog;\
size_t l;\
int llog;\
size_t mask;\
\
dest = _dest;\
\
if (_x >= _y)\
{\
h = _x;\
l = _y;\
}\
else\
{\
h = _y;\
l = _x;\
}\
\
if (l)\
{\
for ((mask=TOP_BIT),(hlog=FULL_BITS-1); !(mask & h); mask >>= 1)\
{\
--hlog;\
}\
if (hlog >= HALF_BITS)\
{\
for (llog = hlog; !(mask & l); mask >>= 1)\
{\
--llog;\
}\
if (((hlog + llog) > (FULL_BITS - 1)) ||\
(((hlog + llog) == (FULL_BITS - 1)) &&\
(((h >> 1) * l + ((h & 1) ? (l >> 1) : 0)) >= TOP_BIT)))\
{\
on_overflow;\
}\
}\
}\
}
-Jerry