home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / rom / utility / sdivmod32.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-03  |  3.7 KB  |  158 lines

  1. /*
  2.     Copyright (C) 1995-1997 AROS - The Amiga Replacement OS
  3.     $Id: sdivmod32.c,v 1.2 1997/02/03 02:58:31 ldp Exp $
  4.  
  5.     Desc: SDivMod32 - Divide two 32 bit numbers.
  6.     Lang: english
  7. */
  8. #include "utility_intern.h"
  9.  
  10. /*****************************************************************************
  11.  
  12.     NAME */
  13. #include <proto/utility.h>
  14.  
  15.         AROS_LH2(QUAD, SDivMod32,
  16.  
  17. /*  SYNOPSIS */
  18.         AROS_LHA(LONG, dividend, D0),
  19.         AROS_LHA(LONG, divisor, D1),
  20.  
  21. /*  LOCATION */
  22.         struct UtilityBase *, UtilityBase, 25, Utility)
  23.  
  24. /*  FUNCTION
  25.         Calculates the 32-bit signed division of dividend by divisor. That
  26.         is dividend / divisor. Will return both the quotient and the
  27.         remainder.
  28.  
  29.     INPUTS
  30.         dividend    -   The number to divide.
  31.         divisor     -   The to divide by.
  32.  
  33.     RESULT
  34.         For m68k assembly programmers:
  35.             D0: quotient
  36.             D1: remainder
  37.         Others:
  38.             The quotient is returned in the high 32 bits of the result.
  39.             The remainder in the low 32 bits.
  40.  
  41.     NOTES
  42.         The utility.library math functions are unlike all other utility
  43.         functions in that they don't require the library base to be
  44.         loaded in register A6, and they also save the values of the
  45.         address registers A0/A1.
  46.  
  47.         This function is mainly to support assembly programers, and is
  48.         probably of limited use to higher-level language programmers.
  49.  
  50.     EXAMPLE
  51.  
  52.     BUGS
  53.         It is very hard for a C programmer to obtain the value of the
  54.         remainder. In fact, its pretty near impossible.
  55.  
  56.     SEE ALSO
  57.         SMult32(), SMult64(), UDivMod32(), UMult32(), UMult64()
  58.  
  59.     INTERNALS
  60.         This may be handled by code in config/$(KERNEL).
  61.  
  62.     HISTORY
  63.         29-10-95    digulla automatically created from
  64.                             utility_lib.fd and clib/utility_protos.h
  65.  
  66. *****************************************************************************/
  67. {
  68.     AROS_LIBFUNC_INIT
  69.  
  70.     return dividend / divisor;
  71.  
  72. #if 0
  73. #error Sorry, but the SDivMod32() emulation code does NOT work...
  74.     /*
  75.         This does NOT work. Do not even try and use this code...
  76.     */
  77.  
  78.     UWORD a,b,c,d;
  79.     QUAD result;
  80.     LONG quo, rem;
  81.     BOOL neg;
  82.  
  83.     /* Fix everything up so that -ve signs don't vanish */
  84.     if(dividend < 0)
  85.     {
  86.         neg = 1; dividend = -dividend;
  87.     }
  88.     else
  89.         neg = 0;
  90.  
  91.     if(divisor < 0)
  92.     {
  93.         neg ^= 1; divisor = -divisor;
  94.     }
  95.  
  96.     a = dividend >> 16;
  97.     b = dividend & 0xFFFF;
  98.     c = divisor >> 16;
  99.     d = divisor & 0xFFFF;
  100.  
  101.     /* See if the numerator is 32 bits or 16... */
  102.     if(a == 0)
  103.     {
  104.         /* 16 bits */
  105.         if(c != 0)
  106.         {
  107.             /* 16/32 -> quo = 0; rem = dividend */
  108.             quo = 0;
  109.             rem = dividend;
  110.         }
  111.         else
  112.         {
  113.             /* 16/16 -> can be done in native div */
  114.             quo = b / d;
  115.             rem = b % d;
  116.         }
  117.     }
  118.     else
  119.     {
  120.         /* 32 bit numerator */
  121.         if(c != 0)
  122.         {
  123.             /* 32 bit denominator, quo ~= a/c */
  124.             quo = a/c;
  125.         }
  126.         else
  127.         {
  128.             /* 16 bit denominator, quo ~= (a/d) * 65536 */
  129.             quo = (a / d) << 16;
  130.         }
  131.         /* Get the error */
  132.         rem = dividend - UMult32(quo,divisor);
  133.  
  134.         /* Take the remainder down to zero */
  135.         while(rem > 0)
  136.         {
  137.             quo++;
  138.             rem -= divisor;
  139.         }
  140.  
  141.         /* However a -ve remainder is silly,
  142.            this also catches the case when the remainder is < 0 from the
  143.            guess
  144.         */
  145.         while(rem < 0)
  146.         {
  147.             quo--;
  148.             rem += divisor;
  149.         }
  150.     }
  151.  
  152.     return result;
  153.  
  154. #endif
  155.  
  156.     AROS_LIBFUNC_EXIT
  157. } /* SDivMod32 */
  158.