Sindbad~EG File Manager
/*
C code for 32*32 multiply and 64/32 divide.
Original author: Nick Burgoyne
Shipped to Beeson in November 1998
Last modified: 12.5.98
*/
/* All data is 32 bits long and and is unsigned. */
/* -------------------------------------------------------- */
#include <stdio.h>
#define BIGNUMS_DLL
#include "export.h"
#include "bignum.h"
#define ulong unsigned // changed by Beeson from unsigned long
#define HI >>16
#define LO &0xffff
#define UP <<16
/* -------------------------------------------------------- */
void longmult(ulong X,ulong Y,ulong *L,ulong *H)
/* X*Y = H*B + L (B = 2^32) */
{
ulong Xh,Xl,Yh,Yl;
ulong h,i,j,l;
Xh = X HI; // break up X and Y
Yh = Y HI;
Xl = X LO;
Yl = Y LO;
h = Xh*Yh; // the 4 multiplies
l = Xl*Yl;
i = Xh*Yl;
j = Xl*Yh;
h += i HI; // add hi 16 bits to h
h += j HI;
i = i UP; // add lo 16 bits to k
l += i;
if (i > l) h += 1; // carry up if needed
j = j UP;
l += j;
if (j > l) h += 1;
*H = h; // store result
*L = l;
}
/*_______________________________________________________*/
void longdiv(ulong H,ulong L,ulong D,ulong *Q,ulong *R)
/* H*B + L = D*Q + R with R < D, assuming H < D */
/* divide a 64 bit number by a 32 bit number producing a 32-bit quotient
and remainder. Warning: overflow can occur if the true quotient is more
than 32 bits.
H = hi 32 bits of the dividend
L = lo 32 bits of the divident
D = divisor
*Q = quotient
*R = remainder
*/
{
ulong c,d,e,i,p=0,q,s,t;
if (H) goto L1;
*Q = L/D; // short code when H = 0
*R = L - (*Q)*D;
return;
L1: t = 0x80000000; // count leading 0 bits in D
c = 0;
L2: if (t&D) goto L3;
t >>= 1;
c += 1;
goto L2;
L3: if (c == 0) goto L4; // branch if hi bit of D set
D <<= c; // shift D and HB+L by c bits
H <<= c;
t = L;
d = 32-c;
t >>= d;
H += t;
L <<= c;
L4: d = D HI; // d is the 16 bit divisor
d += 1; // have 0x8000 < d � 0x10000
e = D LO;
e = 0x10000-e; // 0 < e � 0x10000
s = L HI; // hi part of L
i = 0; // count the two steps
L5: q = H/d; // divide
t = q*d; // 16 bit multiply
H -= t; // H is now the remainder
H = H UP;
H += s; // add hi or lo part of L
t = q*e; // 16 bit multiply
H += t;
if (H >= t) goto L6; // branch if sum < B (taken 86%)
q += 1; // subtract D and increment q
H -= D;
L6: if (H < D) goto L7; // branch if H < D (taken 76%)
q += 1;
H -= D;
L7: if (i) goto L8; // branch to exit on step 2
p = q UP; // high part of quotient
s = L LO; // lo part of L
i = 1;
goto L5; // do second step
L8: *Q = p+q; // add in lo part of quotient
*R = H>>c; // adjust for initial shift
}
/* -------------------------------------------------------- */
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists