home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Found / ODUtils / ODMathM.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-17  |  4.7 KB  |  227 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ODMath.cpp
  3.  
  4.     Contains:    Math routines (fixed-point and wide) for OpenDoc.
  5.  
  6.     Owned by:    Jens Alfke
  7.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good,
  8.                 Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink,
  9.                 Chris Yerga
  10.  
  11.     Copyright:    © 1987 - 1995 by Apple Computer, Inc., all rights reserved.
  12.  
  13.     Notes:
  14.         The PowerPC definitions of many of these functions are already built
  15.         into the Mac OS, so they are compiled here only for 68k. Likewise,
  16.         the 68k definitions of some of these functions are coded in assembly
  17.         language in ODMathM.a, and they are compiled here only for PowerPC.
  18.     
  19.     To Do:
  20.     In Progress:
  21.         
  22. */
  23.  
  24.  
  25. #ifndef _ODMATH_
  26. #include "ODMath.h"
  27. #endif
  28.  
  29. #ifndef __FIXMATH__
  30. #include <FixMath.h>
  31. #endif
  32.  
  33.  
  34. //=============================================================================
  35. // Constants
  36. //=============================================================================
  37.  
  38.  
  39. #define longSize        32
  40. #define wideSize        64
  41.  
  42. #define highBit            ((ODULong) 0x80000000)
  43.  
  44.  
  45. //=============================================================================
  46. // Wide Math For Non-PowerPC
  47. //=============================================================================
  48.  
  49.  
  50. #if !defined(powerc) && !defined(__powerc)
  51.  
  52.  
  53. ODFixed lastSinCosAngle = 0;    // Globals used in .a file
  54. ODFract lastSine = 0,
  55.         lastCosine = kODFract1;
  56.  
  57.  
  58. // Wide math routines are already in the OS on Power Macs.
  59.  
  60.  
  61. ODSShort ODWideCompare(const ODWide *a, const ODWide *b)
  62. {
  63.     if (a->hi > b->hi) return 1;
  64.     if (a->hi < b->hi) return -1;
  65.     if (a->lo > b->lo) return 1;
  66.     if (a->lo < b->lo) return -1;
  67.     return 0;
  68. }
  69.  
  70.  
  71. ODWide *
  72. ODWideNegate(register ODWide *dst)
  73. {
  74.     if (dst->lo) {
  75.         dst->lo = -dst->lo;
  76.         dst->hi = ~dst->hi;
  77.     } else
  78.         dst->hi = -dst->hi;
  79.     return dst;
  80. }
  81.  
  82.  
  83. /* Shift a ODWide to the right (shift > 0) or left (shift < 0) */
  84. ODWide *
  85. ODWideShift(register ODWide *src, register ODSShort shift)
  86. {
  87.     register long x = src->hi, y = src->lo;
  88.     if (shift > 0)
  89.         if (shift >= longSize)
  90.         {    src->hi = -(x < 0);
  91.             src->lo = x >> shift - longSize;
  92.             if (shift == longSize && y < 0 || x << wideSize - shift < 0)
  93.                 ++src->lo || ++src->hi;
  94.         }
  95.         else
  96.         {    src->hi = x >> shift;
  97.             src->lo = x << longSize - shift | (unsigned long)y >> shift;
  98.             if (y << longSize - shift < 0)
  99.                 ++src->lo || ++src->hi;
  100.         }
  101.     else if ( (shift = -shift) != 0 )
  102.         if (shift >= longSize)
  103.         {    src->hi = y << shift - longSize;
  104.             src->lo = 0;
  105.         }
  106.         else
  107.         {    src->hi = x << shift | (unsigned long)y >> longSize - shift;
  108.             src->lo = y << shift;
  109.         }
  110.     return src;
  111. }
  112.  
  113.  
  114. ODWide *
  115. ODWideAdd(register ODWide *dst, register const ODWide *src)
  116. {
  117.     dst->lo += src->lo;
  118.     if (dst->lo < src->lo)
  119.         dst->hi += src->hi + 1;
  120.     else
  121.         dst->hi += src->hi;
  122.     return dst;
  123. }
  124.  
  125.  
  126. ODWide *
  127. ODWideSubtract(register ODWide *dst, register const ODWide *src)
  128. {
  129.     if (dst->lo < src->lo)
  130.         dst->hi -= src->hi + 1;
  131.     else
  132.         dst->hi -= src->hi;
  133.     dst->lo -= src->lo;
  134.     return dst;
  135. }
  136.  
  137.  
  138. // ODWideMultiply and ODWideDivide are in ODMathM.a
  139.  
  140.  
  141.  
  142. //=============================================================================
  143. // Wide Math  & Bit-Twiddling For PowerPC
  144. //=============================================================================
  145.  
  146.  
  147. #else /*powerc*/
  148.  
  149.  
  150. ODSShort
  151. ODFirstBit( ODSLong x )                // JPA: I wrote this from scratch
  152. {
  153.     ODSShort bit = 0;
  154.  
  155.     if (x == 0)
  156.         return -1;
  157.  
  158.     if (x >= 1UL << 16)
  159.         bit += 16, x >>= 16;
  160.     if (x >= 1UL << 8)
  161.         bit += 8, x >>= 8;
  162.     if (x >= 1UL << 4)
  163.         bit += 4, x >>= 4;
  164.     if (x >= 1UL << 2)
  165.         bit += 2, x >>= 2;
  166.     if (x >= 1UL << 1)
  167.         bit += 1;
  168.     return bit;
  169. }
  170.  
  171. #undef ODWideCompare
  172. ODSShort ODWideCompare(const ODWide *a, const ODWide *b)
  173. {
  174.     return (ODSShort) WideCompare(a,b);
  175. }
  176.  
  177. #undef ODWideNegate
  178. ODWide * ODWideNegate(register ODWide *dst)
  179. {
  180.     return (ODWide*) WideNegate(dst);
  181. }
  182.  
  183. #undef ODWideShift
  184. ODWide * ODWideShift(register ODWide *src, register ODSShort shift)
  185. {
  186.     return (ODWide*) WideShift(src,(long)shift);
  187. }
  188.  
  189. #undef ODWideAdd
  190. ODWide * ODWideAdd(register ODWide *dst, register const ODWide *src)
  191. {
  192.     return (ODWide*) WideAdd(dst,src);
  193. }
  194.  
  195. #undef ODWideSubtract
  196. ODWide * ODWideSubtract(register ODWide *dst, register const ODWide *src)
  197. {
  198.     return (ODWide*) WideSubtract(dst,src);
  199. }
  200.  
  201. #undef ODWideDivide
  202. ODSLong ODWideDivide( register const ODWide *dividend,
  203.                             ODSLong divisor, ODSLong *remainder)
  204. {
  205.     return (ODSLong) WideDivide(dividend,divisor,remainder);
  206. }
  207.  
  208. #undef ODWideSquareRoot
  209. ODULong ODWideSquareRoot(register const ODWide *src)
  210. {
  211.     return (ODULong) WideSquareRoot(src);
  212. }
  213.  
  214. ODFract
  215. ODFractSinCos( ODFixed angle, ODFract *cos )
  216. {
  217.     // I have no idea whether FracSin and FracCos are native ... if not,
  218.     // this will be much slower than it could be. But is this every going
  219.     // to be a bottleneck?   [OPTIMIZATION]
  220.     
  221.     if( cos )
  222.         *cos = FracCos(angle);
  223.     return FracSin(angle);
  224. }
  225.  
  226. #endif /*powerc*/
  227.