home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / Emulatory / AROS / utility / smult32.c < prev    next >
Encoding:
C/C++ Source or Header  |  1978-03-06  |  2.6 KB  |  115 lines

  1. /*
  2.     $Id: smult32.c,v 1.3 1996/10/24 22:51:46 aros Exp $
  3.     $Log: smult32.c,v $
  4.     Revision 1.3  1996/10/24 22:51:46  aros
  5.     Use proper Amiga datatypes (eg: ULONG not unsigned long)
  6.  
  7.     Revision 1.2  1996/10/24 15:51:36  aros
  8.     Use the official AROS macros over the __AROS versions.
  9.  
  10.     Revision 1.1  1996/08/31 12:58:13  aros
  11.     Merged in/modified for FreeBSD.
  12.  
  13.     Desc:
  14.     Lang: english
  15. */
  16. #include "utility_intern.h"
  17.  
  18. /*****************************************************************************
  19.  
  20.     NAME */
  21.         #include <clib/utility_protos.h>
  22.  
  23.         AROS_LH2(LONG, SMult32,
  24.  
  25. /*  SYNOPSIS */
  26.         AROS_LHA(LONG, arg1, D0),
  27.         AROS_LHA(LONG, arg2, D1),
  28.  
  29. /*  LOCATION */
  30.         struct UtilityBase *, UtilityBase, 23, Utility)
  31.  
  32. /*  FUNCTION
  33.         Performs the signed 32-bit multiplication of arg1 * arg2 and
  34.         returns a signed 32 bit value.
  35.  
  36.     INPUTS
  37.         arg1, arg2  -   32 bit signed longs
  38.  
  39.     RESULT
  40.         arg1 * arg2
  41.  
  42.     NOTES
  43.         This can perform the multiplication either using the machines
  44.         native instructions (if they exist), or in software using a
  45.         simple algorithm based on expanding algebraic products.
  46.  
  47.     EXAMPLE
  48.  
  49.         LONG a = 352543;
  50.         LONG b = -52464;
  51.         LONG c = SMult32(a,b);
  52.         c == -1315946768
  53.  
  54.     BUGS
  55.  
  56.     SEE ALSO
  57.         utility/UMult32(), utility/UMult64(), utility/SMult64()
  58.  
  59.     INTERNALS
  60.         We are performing the operation:
  61.  
  62.  
  63.             (2^16 * a + b) * (2^16 * c + d)
  64.           = 2^32 * ab + 2^16 * ad + 2^16 * bc + bd
  65.           = 2^32 * ab + 2^16 ( ad + bc ) + bd
  66.  
  67.         Now since the result is a 32-bit number, the 2^32 term will have
  68.         no effect. (Since 2^32 > max (32-bit number).
  69.  
  70.         Therefore:
  71.         product = 2^16( ad + bc ) + bd
  72.  
  73.     HISTORY
  74.         29-10-95    digulla automatically created from
  75.                             utility_lib.fd and clib/utility_protos.h
  76.         18-08-96    iaint   Implemented as described above.
  77.  
  78. *****************************************************************************/
  79. {
  80.     AROS_LIBFUNC_INIT
  81.  
  82. #ifdef HAS_32BITMULS
  83.     return arg1 * arg2;
  84. #else
  85.  
  86.     UWORD a1, b1, a0, b0;
  87.     BOOL neg;
  88.  
  89.     /* Fix everything up so that -ve signs don't vanish */
  90.     if(arg1 < 0)
  91.     {
  92.         neg = 1; arg1 = -arg1;
  93.     }
  94.     else
  95.         neg = 0;
  96.  
  97.     if(arg2 <= 0)
  98.     {
  99.         neg ^= 1; arg2 = -arg2; 
  100.     }
  101.  
  102.     /* The compiler should optimize these div/mults by 65536. */
  103.  
  104.     a1 = (arg1 >> 16) & 0xffff;
  105.     a0 = arg1 & 0xffff;
  106.     b1 = (arg2 >> 16) & 0xffff;
  107.     b0 = arg2 & 0xffff;
  108.  
  109.     arg1 = (((a0 * b1) + (a1 * b0)) <<16) + (b0 * a0);
  110.     return (neg ? -arg1 : arg1);
  111. #endif
  112.  
  113.     AROS_LIBFUNC_EXIT
  114. } /* SMult32 */
  115.