home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 1.ddi / WINLBSRC.ZIP / NECP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  4.2 KB  |  166 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - necp.c
  3.  *
  4.  * function(s)
  5.  *        necPow10 - power 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. #define I asm
  18.  
  19. /*--------------------------------------------------------------------------*
  20.  
  21. Name            necPow10 - power function, 10^p
  22.  
  23. Usage           double  necPow10(int  p);
  24.  
  25. Prototype in    math.h
  26.  
  27. Description     Calculate 10  raised to power.  A lookup table  is used for
  28.                 values  from  10  through  10^15,  then this is augmented by
  29.                 multiplying with  table entries for  10^16/32/64/128/256,
  30.                 which allows any power up to the implementation limit of 511.
  31.  
  32.                 The usual range of double precision is  10e308 but necPow10
  33.                 has a wider  range so that it can be used for long double
  34.                 calculations when the result is retrieved off the TOS
  35.                 explicitly by inline code doing a store of an 80 bit #.
  36.  
  37.                 Negative powers are provided by a final division.
  38.  
  39.                 All registers  are preserved except   AX ! This  is done to
  40.                 enable  use by  xcvt(), which  was designed  to assume  its
  41.                 registers will be undisturbed.
  42.  
  43. Return value    necPow10 returns 10^p.
  44.  
  45. *---------------------------------------------------------------------------*/
  46.  
  47. double  pascal near __necPow10  (int  p)
  48. {
  49. #define MAX_87_EXP      511
  50.  
  51. I       mov     ax, p
  52.     if ((int)_AX < -MAX_87_EXP)     /* Extremely small -> Zero      */
  53.     {
  54. I       FLDZ
  55. I       jmp     p10_end
  56. /*
  57.         This is a convenient place to tuck our tables into.
  58.         We want to force the tables to reside in the code segment.
  59.         To do this in TC, disguise them as PROCs.
  60. */
  61. I e0to10        PROC
  62. I       dd      1.e0,  1.e1,  1.e2,  1.e3,  1.e4
  63. I       dd      1.e5,  1.e6,  1.e7,  1.e8,  1.e9,  1.e10
  64. I e0to10        ENDP
  65.  
  66. I e11to15       PROC
  67. I       dq      1.e11, 1.e12, 1.e13, 1.e14, 1.e15
  68. I e11to15       ENDP
  69.  
  70. I e16   PROC
  71. I       dq      1.e16
  72. I e16   ENDP
  73. I e32   PROC
  74. I       dt      40699DC5ADA82B70B59Eh
  75. I e32   ENDP
  76. I e64   PROC
  77. I       dt      40D3C2781F49FFCFA6D5h
  78. I e64   ENDP
  79. I e128  PROC
  80. I       dt      41A893BA47C980E98CDFh
  81. I e128  ENDP
  82. I e256  PROC
  83. I       dt      4351AA7EEBFB9DF9DE8Ch
  84. I e256  ENDP
  85.  
  86. I eINF  PROC
  87. I       dd      7F800000h       /* +infinity    */
  88. I eINF  ENDP
  89.     }
  90.  
  91.     if ((int)_AX >  MAX_87_EXP)     /* Extremely large -> Infinity  */
  92.     {
  93. I       FLD     dword ptr eINF
  94. I       jmp     p10_end
  95.     }
  96.  
  97. I       or      ax, ax
  98. I       jnl     p10_abs
  99. I       neg     ax
  100.  
  101. p10_abs:
  102. I       mov     si, 15
  103. I       and     si, ax
  104. I       shl     si, 1
  105. I       shl     si, 1
  106. I       sub     si, 44
  107. I       jnl     p10_11to15
  108. I       FLD     dword ptr (e0to10) [si+44]
  109. I       jmp     short   p10_bigger
  110.  
  111. p10_11to15:
  112. I       shl     si, 1
  113. I       FLD     qword ptr (e11to15) [si]
  114.  
  115. p10_bigger:
  116. I       shr     ax, 1
  117. I       shr     ax, 1
  118. I       shr     ax, 1
  119. I       shr     ax, 1
  120. I       jz      p10_checkSign           /* optimization, skip if all done */
  121. I       shr     ax, 1
  122. I       jnc     p10_maybe32
  123. I       FMUL    qword ptr (e16)
  124.  
  125. p10_maybe32:
  126. I       shr     ax, 1
  127. I       jnc     p10_maybe64
  128. I       FLD     tbyte ptr (e32)
  129. I       FMUL
  130.  
  131. p10_maybe64:
  132. I       shr     ax, 1
  133. I       jnc     p10_maybe128
  134. I       FLD     tbyte ptr (e64)
  135. I       FMUL
  136.  
  137. p10_maybe128:
  138. I       shr     ax, 1
  139. I       jnc     p10_maybe256
  140. I       FLD     tbyte ptr (e128)
  141. I       FMUL
  142.  
  143. p10_maybe256:
  144. I       shr     ax, 1
  145. I       jnc     p10_checkSign
  146. I       FLD     tbyte ptr (e256)
  147. I       FMUL
  148.  
  149. p10_checkSign:
  150. I       test    byte ptr (p) [1], 80h
  151. I       jz      p10_end
  152.  
  153. /* 10^(-n) = 1 / 10^n, so we need the reciprocal of TOS. */
  154.  
  155. I       FLD1
  156. I       FDIVR                           /* TOS = 1.0 / TOS */
  157.  
  158. /* Now the value 10^p is on TOS. */
  159.  
  160. p10_end:
  161. #pragma warn -rvl
  162.     return;
  163. #pragma warn .rvl
  164. }
  165.  
  166.