home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / MATHSRC.ZIP / _POW10.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  5.6 KB  |  198 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - _pow10.cas
  3.  *
  4.  * function(s)
  5.  *        __pow10 - long double power internal library function, 10^p
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*
  9.  *      C/C++ Run Time Library - Version 5.0
  10.  *
  11.  *      Copyright (c) 1987, 1992 by Borland International
  12.  *      All Rights Reserved.
  13.  *
  14.  */
  15.  
  16. #pragma inline
  17. #include <asmrules.h>
  18.  
  19. #include <_math.h>
  20. #include <math.h>
  21. #include <errno.h>
  22. #include <stddef.h>
  23.  
  24. typedef unsigned short int  extend [5];     /* 80-bit constants */
  25.  
  26. static  const   float   e0to7 [8] =
  27. {
  28.     1, 1.e1,  1.e2,  1.e3,  1.e4,  1.e5,  1.e6,  1.e7,
  29. };
  30.  
  31. /* Exponents > 4932 become infinities.  Exponents < -4932 become 0. */
  32.  
  33. /* These values have been calculated with extra precision to ensure  */
  34. /* that the last bit is rounded correctly.                           */
  35. static  const   float   e8    = 1.e8;
  36. static  const   double  e16   = 1.e16;
  37. static  const   extend  e32   = {0xB59E, 0x2B70, 0xADA8, 0x9DC5, 0x4069};
  38. static  const   extend  e64   = {0xA6D5, 0xFFCF, 0x1F49, 0xC278, 0x40D3};
  39. static  const   extend  e128  = {0x8CE0, 0x80E9, 0x47C9, 0x93BA, 0x41A8};
  40. static  const   extend  e256  = {0xDE8E, 0x9DF9, 0xEBFB, 0xAA7E, 0x4351};
  41. static  const   extend  e512  = {0x91C7, 0xA60E, 0xA0AE, 0xE319, 0x46A3};
  42. static  const   extend  e1024 = {0x0C17, 0x8175, 0x7586, 0xC976, 0x4D48};
  43. static  const   extend  e2048 = {0x5DE5, 0xC53D, 0x3B5D, 0x9E8B, 0x5A92};
  44. static  const   extend  e4096 = {0x979B, 0x8A20, 0x5202, 0xC460, 0x7525};
  45. static  const   float   eINF  = 1.0/0.0;
  46.  
  47.  
  48. /*--------------------------------------------------------------------------*
  49.  
  50. Name            __pow10 - long double power function, 10^p
  51.  
  52. Usage           long double near __pow10(int  p);
  53.  
  54. Prototype in    math.h
  55.  
  56. Description     Calculate 10 raised to power.  A lookup table  is used for
  57.                 values  from  10  through  10^7,  then this is augmented by
  58.                 multiplying with  table entries for  10^8/16/32/64/128/256,
  59.                 512/1024/2048/4096 which allows any power up to the
  60.                 implementation limit of 4932.
  61.  
  62.                 Negative powers are provided by a final division.
  63.  
  64.                 All registers  are preserved except   AX.  This  is done to
  65.                 enable  use by  xcvt(), which  was designed  to assume  its
  66.                 registers will be undisturbed.
  67.  
  68.                 This is an internal library function used by pow10 and
  69.                 pow10l.
  70.  
  71. Return value    __pow10 returns 10^p.
  72.  
  73. *---------------------------------------------------------------------------*/
  74. #pragma warn -rvl
  75. long double pascal near __pow10  (int  p)
  76. {
  77. #define MAX_87_EXP      4932
  78.  
  79. #ifdef __HUGE__
  80. asm     mov     ax, seg e0to7
  81. asm     mov     DS, ax
  82. #endif
  83.  
  84. /*--------------------------------------------------------------------------
  85.         Take care of all the easy special cases up front.
  86. --------------------------------------------------------------------------*/
  87. asm     mov     ax, p
  88.         if ((int)_AX < -MAX_87_EXP)     /* Extremely small -> Zero      */
  89.                 {
  90. asm             FLDZ
  91. asm             jmp     p10_end
  92.                 }
  93.         if ((int)_AX >  MAX_87_EXP)     /* Extremely large -> Infinity  */
  94.                 {
  95. asm             FLD     FLOAT(eINF)
  96. asm             jmp     p10_end
  97.                 }
  98.         if ((int)_AX == 0)              /* 10^0 -> 1.0                  */
  99.                 {
  100. asm             FLD1
  101. asm             jmp     p10_end
  102.                 }
  103.  
  104. /*--------------------------------------------------------------------------
  105.                 The non-trivial cases require some calculation.
  106. --------------------------------------------------------------------------*/
  107. /*asm   mov     ax, p*/
  108. asm     or      ax, ax
  109. asm     jnl     p10_abs
  110. asm     neg     ax
  111.  
  112. p10_abs:
  113. asm     mov     si, 7
  114. asm     and     si, ax
  115. asm     shl     si, 1
  116. asm     shl     si, 1
  117. asm     FLD     FLOAT (e0to7 [si])
  118.  
  119. asm     shr     ax, 1
  120. asm     shr     ax, 1
  121. asm     shr     ax, 1
  122.  
  123. p10_maybe8:
  124. asm     shr     ax, 1
  125. asm     jnc     p10_maybe16
  126. asm     FMUL    FLOAT (e8)
  127.  
  128. p10_maybe16:
  129. asm     jnz     keep_going
  130. asm     jmp     p10_checkSign           /* optimization, skip if all done */
  131. keep_going:
  132. asm     shr     ax, 1
  133. asm     jnc     p10_maybe32
  134. asm     FMUL    DOUBLE (e16)
  135.  
  136. p10_maybe32:
  137. asm     shr     ax, 1
  138. asm     jnc     p10_maybe64
  139. asm     FLD     LONGDOUBLE (e32)
  140. asm     FMUL
  141.  
  142. p10_maybe64:
  143. asm     shr     ax, 1
  144. asm     jnc     p10_maybe128
  145. asm     FLD     LONGDOUBLE (e64)
  146. asm     FMUL
  147.  
  148. p10_maybe128:
  149. asm     shr     ax, 1
  150. asm     jnc     p10_maybe256
  151. asm     FLD     LONGDOUBLE (e128)
  152. asm     FMUL
  153.  
  154. p10_maybe256:
  155. asm     shr     ax, 1
  156. asm     jnc     p10_maybe512
  157. asm     FLD     LONGDOUBLE (e256)
  158. asm     FMUL
  159.  
  160. p10_maybe512:
  161. asm     shr     ax, 1
  162. asm     jnc     p10_maybe1024
  163. asm     FLD     LONGDOUBLE (e512)
  164. asm     FMUL
  165.  
  166. p10_maybe1024:
  167. asm     shr     ax, 1
  168. asm     jnc     p10_maybe2048
  169. asm     FLD     LONGDOUBLE (e1024)
  170. asm     FMUL
  171.  
  172. p10_maybe2048:
  173. asm     shr     ax, 1
  174. asm     jnc     p10_maybe4096
  175. asm     FLD     LONGDOUBLE (e2048)
  176. asm     FMUL
  177.  
  178. p10_maybe4096:
  179. asm     shr     ax, 1
  180. asm     jnc     p10_checkSign
  181. asm     FLD     LONGDOUBLE (e4096)
  182. asm     FMUL
  183.  
  184. p10_checkSign:
  185. asm     test    BY1 (p), 80h
  186. asm     jz      p10_end
  187.  
  188. /* 10^(-n) = 1 / 10^n, so we need the reciprocal of TOS. */
  189.  
  190. asm     FDIVR   FLOAT (e0to7)           /* TOS = 1.0 / TOS */
  191.  
  192. /* Now the value 10^p is on TOS. */
  193.  
  194. p10_end:
  195.     return;
  196. }
  197. #pragma warn .rvl
  198.