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 / OS / FWODMisc / FWFxMath.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  8.6 KB  |  337 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWFxMath.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWFXMATH_H
  13. #include "FWFxMath.h"
  14. #endif
  15.  
  16. #ifndef FWSTREAM_H
  17. #include "FWStream.h"
  18. #endif
  19.  
  20. #ifdef FW_DEBUG
  21. #include <stdio.h>
  22. #endif
  23.  
  24. #ifdef FW_BUILD_MAC
  25. #pragma segment fwodmisc_fixedmath
  26. #endif
  27.  
  28. //========================================================================================
  29. // FW_Fixed
  30. //========================================================================================
  31.  
  32. //----------------------------------------------------------------------------------------
  33. //    FW_Sin
  34. //----------------------------------------------------------------------------------------
  35.  
  36. FW_Fixed FW_Sin(FW_Fixed f)
  37. {
  38. #ifdef FW_BUILD_MAC68K
  39.     // [BRP] Work around an OpenDoc bug on 68k machines that
  40.     //    !!! do not have an FPU installed, at the expense of precision
  41.     FW_Fixed result;
  42.     result.fRep = ::Frac2Fix(::FracSin(f.fRep));
  43.     return result;
  44. #else
  45.     ODFract fract = ODFractSinCos(f.fRep, NULL);
  46.     return FW_ODFixedToFixed(fract >> 14);
  47. #endif
  48. }
  49.  
  50. //----------------------------------------------------------------------------------------
  51. //    FW_Cos
  52. //----------------------------------------------------------------------------------------
  53.  
  54. FW_Fixed FW_Cos(FW_Fixed f)
  55. {
  56. #ifdef FW_BUILD_MAC68K
  57.     // [BRP] Work around an OpenDoc bug on 68k machines that
  58.     //    !!! do not have an FPU installed, at the expense of precision
  59.     FW_Fixed result;
  60.     result.fRep = ::Frac2Fix(::FracCos(f.fRep));
  61.     return result;
  62. #else
  63.     ODFract frac;
  64.     ODFractSinCos(f.fRep, &frac);
  65.     return FW_ODFixedToFixed(frac >> 14);
  66. #endif
  67. }
  68.  
  69. //----------------------------------------------------------------------------------------
  70. //    FW_Sqrt
  71. //----------------------------------------------------------------------------------------
  72.  
  73. FW_Fixed FW_Sqrt(FW_Fixed f)
  74. {
  75.     ODWide wide;
  76.     wide.hi = 0;
  77.     wide.lo = f.fRep;
  78.     ODWideShift(&wide, -16);
  79.     
  80.     ODFixed fixed = ODWideSquareRoot(&wide);
  81.     return FW_ODFixedToFixed(fixed);
  82. }
  83.  
  84. //========================================================================================
  85. // FW_Wide
  86. //========================================================================================
  87.  
  88. //----------------------------------------------------------------------------------------
  89. //    FW_IntToWide
  90. //----------------------------------------------------------------------------------------
  91.  
  92. FW_Wide FW_IntToWide(int i)
  93. {
  94.     ODWide w = { i, 0 };
  95.     return FW_ODWideToWide(w);
  96. }
  97.  
  98. //----------------------------------------------------------------------------------------
  99. //    priv_f2w
  100. //----------------------------------------------------------------------------------------
  101.  
  102. static FW_Wide priv_f2w(ODFixed lo)
  103. {
  104.     long   hi = (lo & 0x80000000) ? -1L : 0L;
  105.     ODWide w  = { hi, lo };
  106.     ODWideShift(&w, -16);
  107.     return FW_ODWideToWide(w);
  108. }
  109.  
  110. //----------------------------------------------------------------------------------------
  111. //    FW_FixedToWide
  112. //----------------------------------------------------------------------------------------
  113.  
  114. FW_Wide FW_FixedToWide(FW_Fixed f)
  115. {
  116.     return priv_f2w(f.fRep);
  117. }
  118.  
  119. //----------------------------------------------------------------------------------------
  120. //    FW_ODFixedToWide
  121. //----------------------------------------------------------------------------------------
  122.  
  123. FW_Wide FW_ODFixedToWide(ODFixed f)
  124. {
  125.     return priv_f2w(f);
  126. }
  127.  
  128. //----------------------------------------------------------------------------------------
  129. //    FW_WideToInt
  130. //----------------------------------------------------------------------------------------
  131.  
  132. int    FW_WideToInt(const FW_Wide& w1)
  133. {
  134.     ODWide w = w1.fRep;
  135.     ODWide h = { 0, 0x80000000l };
  136.     ODWideAdd(&w, &h);
  137.     return w.hi;
  138. }
  139.  
  140. //----------------------------------------------------------------------------------------
  141. //    FW_WideToODFixed
  142. //----------------------------------------------------------------------------------------
  143.  
  144. ODFixed    FW_WideToODFixed(const FW_Wide& w1)
  145. {
  146.     ODWide w = w1.fRep;
  147.     ODWide h = { 0, 0x00008000l };
  148.     ODWideAdd(&w, &h);
  149.  
  150.     const signed long  FW_kPrivMaxSignedWideToFixedInt = 0x00007FFF;
  151.     const signed long  FW_kPrivMinSignedWideToFixedInt = 0xFFFF8000;
  152.  
  153.     const ODFixed FW_kPrivMaxFixed = 0x7FFFFFFF;
  154.     const ODFixed FW_kPrivMinFixed = 0x80000000;
  155.     
  156.     if (w.hi > FW_kPrivMaxSignedWideToFixedInt)
  157.         return FW_kPrivMaxFixed;
  158.     
  159.     if (w.hi < FW_kPrivMinSignedWideToFixedInt)
  160.         return FW_kPrivMinFixed;
  161.         
  162.     return (w.hi << 16) | (w.lo >> 16);
  163. }
  164.  
  165. //----------------------------------------------------------------------------------------
  166. //    operator +
  167. //----------------------------------------------------------------------------------------
  168.  
  169. FW_Wide operator +    (const FW_Wide& w1, const FW_Wide& w2)
  170. {
  171.     ODWide w = w1.fRep;
  172.     ODWideAdd(&w, &w2.fRep);
  173.     return FW_ODWideToWide(w);
  174. }
  175.  
  176. //----------------------------------------------------------------------------------------
  177. //    operator -
  178. //----------------------------------------------------------------------------------------
  179.  
  180. FW_Wide operator -    (const FW_Wide& w1, const FW_Wide& w2)
  181. {
  182.     ODWide w = w1.fRep;
  183.     ODWideSubtract(&w, &w2.fRep);
  184.     return FW_ODWideToWide(w);
  185. }
  186.  
  187. //----------------------------------------------------------------------------------------
  188. //    FW_WideMultiply
  189. //----------------------------------------------------------------------------------------
  190.  
  191. FW_Wide FW_WideMultiply (FW_Fixed f1, FW_Fixed f2)
  192. {
  193.     ODWide w;
  194.     ODWideMultiply(f1.fRep, f2.fRep, &w);
  195.     return FW_ODWideToWide(w);
  196. }
  197.  
  198. //----------------------------------------------------------------------------------------
  199. //    operator /
  200. //----------------------------------------------------------------------------------------
  201.  
  202. FW_Fixed operator /    (const FW_Wide& w1, FW_Fixed f2)
  203. {
  204.     return FW_ODFixedToFixed(ODWideDivide(&w1.fRep, f2.fRep, NULL));
  205. }
  206.  
  207. //========================================================================================
  208. //    Global operators << and >>
  209. //========================================================================================
  210.  
  211. FW_CWritableStream& operator<<(FW_CWritableStream& stream, const FW_Fixed& fx)
  212. {
  213.     stream << fx.fRep;
  214.     return stream;
  215. }
  216.  
  217. FW_CReadableStream& operator>>(FW_CReadableStream& stream, FW_Fixed& fx)
  218. {
  219.     stream >> fx.fRep;
  220.     return stream;
  221. }
  222.  
  223. #ifdef FW_DEBUG
  224.  
  225. //========================================================================================
  226. //    Debug versions of math operators
  227. //========================================================================================
  228.  
  229. static void FixedError(FW_Fixed f1, FW_Fixed f2, const char* lpsz)
  230. {
  231.     char buf[250];
  232.     sprintf(buf, "Fixed error: %s, %.2f, %.2f", lpsz, FW_FixedToDouble(f1), FW_FixedToDouble(f2));
  233.     FW_DEBUG_MESSAGE(buf);
  234. }
  235.  
  236. FW_Fixed operator+(FW_Fixed f1, FW_Fixed f2)
  237. {
  238.     long rep1 = f1.fRep;
  239.     long rep2 = f2.fRep;
  240.  
  241.     long repr  = (rep1 >> 16) + (rep2 >> 16);
  242.  
  243.     if (repr < -32768 || repr > 32767)
  244.         FixedError(f1, f2, "Add oflw");
  245.  
  246.     return FW_ODFixedToFixed(f1.fRep + f2.fRep);
  247. }
  248.  
  249. FW_Fixed operator-(FW_Fixed f1, FW_Fixed f2)
  250. {
  251.     long rep1 = f1.fRep;
  252.     long rep2 = f2.fRep;
  253.  
  254.     long repr  = (rep1 >> 16) - (rep2 >> 16);
  255.  
  256.     if (repr < -32768 || repr > 32767)
  257.         FixedError(f1, f2, "Sub oflw");
  258.  
  259.     return FW_ODFixedToFixed(f1.fRep - f2.fRep);
  260. }
  261.  
  262. FW_Wide& operator += (FW_Wide& w1, const FW_Fixed& f2)
  263. {
  264.     FW_Wide w2 = FW_FixedToWide(f2);
  265.     return w1 += w2;
  266. }
  267.  
  268. FW_Wide& operator -= (FW_Wide& w1, const FW_Fixed& f2)
  269. {
  270.     FW_Wide w2 = FW_FixedToWide(f2);
  271.     return w1 -= w2;
  272. }
  273.  
  274. FW_Fixed operator*(FW_Fixed f1, FW_Fixed f2)
  275. {
  276.     long rep1 = f1.fRep;
  277.     long rep2 = f2.fRep;
  278.  
  279.     long repr  = (rep1 >> 16) * (rep2 >> 16);
  280.     
  281.     if (repr < -32768 || repr > 32767)
  282.         FixedError(f1, f2, "Mul oflw");
  283.  
  284.     return FW_ODFixedToFixed(ODFixedMultiply(f1.fRep, f2.fRep));
  285. }
  286.  
  287. FW_Fixed operator/(FW_Fixed f1, FW_Fixed f2)
  288. {
  289.     if (f2.fRep == 0)
  290.         FixedError(f1, f2, "Div by 0");
  291.  
  292.     return FW_ODFixedToFixed(ODFixedDivide(f1.fRep, f2.fRep));
  293. }
  294.  
  295. #endif
  296.  
  297. #include <math.h>
  298.  
  299. // #ifdef FW_BUILD_WIN
  300. // [KVV] OpenDoc DR2 for Windows is missing the following routines
  301.  
  302. #ifdef FW_BUILD_WIN
  303. ODFract    ODFractSinCos(ODFixed angle, ODFract *cosResult)
  304. {
  305.     FW_Double flAngle    = ODFixedToDouble(angle);
  306.  
  307.     FW_Double flSin    = sin(flAngle);
  308.     FW_Double flCos    = cos(flAngle);
  309.     
  310.     ODFixed fxSin    = ODDoubleToFixed(flSin);
  311.     ODFixed fxCos    = ODDoubleToFixed(flCos);
  312.     
  313.     if(cosResult != NULL)
  314.         *cosResult = ODFixedToFract(fxCos);
  315.         
  316.     return ODFixedToFract(fxSin);
  317. }
  318. #endif
  319.  
  320. #ifdef FW_BUILD_WIN
  321.  
  322. ODULong ODWideSquareRoot(const ODWide *src)
  323. {
  324.     if(src->hi == 0 && src->lo == 0)
  325.         return 0;
  326.  
  327.     if(src->hi < 0)
  328.         return 0x7FFFFFFFl;
  329.         
  330.     FW_Double d = src->hi + src->lo / 4294967296.0;
  331.     FW_Double s = sqrt(d);
  332.     
  333.     return ODDoubleToFixed(s);
  334. }
  335.  
  336. #endif
  337.