Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/bignums/
Upload File :
Current File : /usr/home/beeson/MathXpert/bignums/nick.x

/* 
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