Sindbad~EG File Manager

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

/* M. Beeson */
/*  multiply two unsigned shorts and get the two digits of the 32-bit answer */
/*  This is 16-bit code only.  Corresponding 32-bit code is in lngmul32.c */
/*  #define NOASM   to use C instead of assembly-language */
/*  In the 32-bit version you MUST use assembly language;
    NOASM only works with 16-bit programs. */

#define BIGNUMS_DLL
#ifdef NOASM
#include "bignum.h"  /* NN */
#if sizeof(long) == 2 * sizeof(int) /* otherwise you MUST use assembly language */

void longmult(unsigned x, unsigned  y, unsigned  *lo, unsigned *hi)
/* multiply two unsigneds getting an answer twice as long */
{ unsigned long ans;
  ans = ((unsigned long) x )* ((unsigned long) y );
  *lo = (unsigned short) (ans & 0xffff);
  *hi = (unsigned short) (ans >> 16);
}
/*_____________________________________________________________________*/
void longdiv(unsigned x, unsigned y, unsigned z, unsigned *q, unsigned *r)
/* divide a 32 bit number by a 16 bit number producing a 16-bit quotient
and remainder.  Warning: overflow can occur if the true quotient is more
than 16 bits.
x = hi 16 bits of the dividend
y = lo 16 bits of the divident
z = divisor
*q = quotient
*r = remainder
*/
{ unsigned long xx = ((x << NN) | y);
  unsigned long qq = xx/z;
  *q = (unsigned) qq;  /* overflow if qq is too large */
  *r = (unsigned) (xx - qq*z);  // corrected 10.30.03.  This code is not used in Mathpert
}
#endif  /* sizeof(long) == 2 * sizeof(int) */

#else
/* from now on, we're using assembly language */

#pragma inline

/* 16-bit code:  */
void longmult(unsigned x, unsigned y, unsigned *lo, unsigned *hi)
/* the assembly-language MUL instruction multiplies register AX by its
argument and leaves the high word in DX and the low word in AX */

{ asm  {
         mov ax, x
         mul word ptr y
       }
  *lo = _AX;
  *hi = _DX;
}
/*___________________________________________________________________*/
void longdiv(unsigned x, unsigned y, unsigned z, unsigned *q, unsigned *r)
/* divide a 32 bit number by a 16 bit number producing a 16-bit quotient
and remainder.  Warning: overflow can occur if the true quotient is more
than 16 bits.
x = hi 16 bits of the dividend
y = lo 16 bits of the divident
z = divisor
*q = quotient
*r = remainder
*/

{ asm  {
         mov edx, x
         mov eax, y
         div word ptr z
       }
  *q = _AX;
  *r = _DX;
}
#endif

#if 0
  // 32 bit versions
/*___________________________________________________________________*/
void longmult(unsigned x, unsigned y, unsigned *lo, unsigned *hi)
/* the assembly-language MUL instruction multiplies register EAX by its
argument and leaves the high word in EDX and the low word in EAX */

{ asm  {
         mov eax, x
         mul word ptr y
       }
  *lo = _EAX;
  *hi = _EDX;
}
/*______________________________________________________________________*/
void longdiv(unsigned x, unsigned y, unsigned z, unsigned *q, unsigned *r)
/* 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.
x = hi 32 bits of the dividend
y = lo 32 bits of the divident
z = divisor
*q = quotient
*r = remainder
*/

{ asm  {
         mov edx, x
         mov eax, y
         div word ptr z
       }
  *q = _EAX;
  *r = _EDX;
}
#endif


Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists