Code Associated with Jack Crenshaw's Programmer's Toolbox, "More on Multiplication" April 1997, pp 19-26 listing 1 Multiplying longs. typedef struct{ unsigned short lo; unsigned short hi; } wordpair; typedef union{ unsigned long lng; wordpair pr; } Long; longlong & longlong::mult(unsigned long &x, const unsigned long &y){ // break input up into 16-bit chunks Long X, Y, high, low, mid, temp; unsigned short a, b, c, d; X.lng = x; Y.lng = y; a = X.pr.hi; b = X.pr.lo; c = Y.pr.hi; d = Y.pr.lo; //multiply each pair of chunks mid.lng = (unsigned long)a * d; high.lng = (unsigned long)a * c; low.lng = (unsigned long)b * d; // add the pieces temp.lng = mid.lng + (unsigned long) low.pr.hi; if(temp.lng < mid.lng) ++high.pr.hi; mid.lng = temp.lng+(unsigned long)b*c; if(mid.lng < temp.lng) ++high.pr.hi; // build the result low.pr.hi = mid.pr.lo; high.lng += mid.pr.hi; lo = low.lng; hi = high.lng; return *this; } listing 2 Low half only. unsigned long mult31(const unsigned long &x, const unsigned long &y){ // break input up into 16-bit chunks Long X, Y, low; unsigned short b, d, mid; X.lng = x; Y.lng = y; b = X.pr.lo; d = Y.pr.lo; //multiply each pair of chunks low.lng = (unsigned long)b * d; mid = X.pr.hi * d + Y.pr.hi * b; // add the pieces low.pr.hi += mid; return low.lng; } listing 3 High half only. unsigned long mult_1(const unsigned long &x, const unsigned long &y){ // break input up into 16-bit chunks Long X, Y, high, low, mid, temp; unsigned short a, b, c, d; X.lng = x; Y.lng = y; a = X.pr.hi; b = X.pr.lo; c = Y.pr.hi; d = Y.pr.lo; //multiply each pair of chunks mid.lng = (unsigned long)a * d; high.lng = (unsigned long)a * c; low.lng = (unsigned long)b * d; // add the pieces temp.lng = mid.lng + (unsigned long)low.pr.hi; if(temp.lng < mid.lng) ++high.pr.hi; mid.lng = temp.lng+(unsigned long)b*c; if(mid.lng < temp.lng) ++high.pr.hi; // build the result high.lng += mid.pr.hi; return high.lng; } listing 4 Multiplying, scale L0. unsigned long mult_L0(const unsigned long &x, const unsigned long &y){ // break input up into 16-bit chunks Long X, Y, high, low, mid, temp; unsigned short a, b, c, d; X.lng = x; Y.lng = y; a = X.pr.hi; b = X.pr.lo; c = Y.pr.hi; d = Y.pr.lo; //multiply each pair of chunks mid.lng = (unsigned long)a * d; high.lng = (unsigned long)a * c; low.lng = (unsigned long)b * d; // add the pieces temp.lng = mid.lng + (unsigned long)low.pr.hi; if(temp.lng < mid.lng) ++high.pr.hi; mid.lng = temp.lng+(unsigned long)b*c; if(mid.lng < temp.lng) ++high.pr.hi; // build the result high.lng += mid.pr.hi; high.lng <<=1; high.lng += ((long)mid.lng <0); return high.lng; } listing 5 Multiplying, scale L15. unsigned long mult_L15(const unsigned long &x, const unsigned long &y){ // break input up into 16-bit chunks Long X, Y, high, low, mid, temp; unsigned short a, b, c, d; X.lng = x; Y.lng = y; a = X.pr.hi; b = X.pr.lo; c = Y.pr.hi; d = Y.pr.lo; //multiply each pair of chunks high.lng = (unsigned long)a * c; mid.lng = (unsigned long)a * d; temp.lng = (unsigned long)b * c; low.lng = (unsigned long)b * d; // add the pieces mid.lng += temp.lng + low.pr.hi; mid.pr.hi += high.pr.lo; return mid.lng; }