home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 1.ddi / MATHSRC.ZIP / FREXP.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  3.2 KB  |  128 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - frexp.cas
  3.  *
  4.  * function(s)
  5.  *        frexp - splits a double number into mantissa and exponent
  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.  
  17. #pragma inline
  18. #include <asmrules.h>
  19.  
  20. #include <_math.h>
  21. #include <math.h>
  22.  
  23. /*--------------------------------------------------------------------------*
  24.  
  25. Name            frexp - splits a double number into mantissa and exponent
  26.  
  27. Usage           double frexp(double value, int *expP);
  28.  
  29. Prototype in    math.h
  30.  
  31. Description     Split  a  floating  point  number  into  its  exponent  and
  32.                 fractional parts, with the  exponent placed into *expP, and
  33.                 the fraction is the function return value.
  34.  
  35. Return value    frexp returns  value - (*expP = chop (value));
  36.  
  37. *---------------------------------------------------------------------------*/
  38. #pragma warn -rvl
  39.  
  40. double _FARFUNC frexp( double value, int *expP )
  41. {
  42.         volatile unsigned statword;
  43.  
  44. #ifdef _Windows
  45.  
  46. // The Microsoft FP emulator does not support the FXTRACT instruction.
  47.  
  48.         _CX = 0;
  49. start:
  50. asm     {
  51.         mov     ax, value[6]
  52.         mov     dx, ax
  53.         and     ax, 7FF0h
  54.         jz      denormal
  55.         sub     dx, ax
  56.         sub     ax, 3FE0h
  57.         or      dx, 3FE0h
  58.         mov     value[6], dx
  59.         FLD     DOUBLE (value)
  60.         sub     ax, cx          // possible denormal adjustment
  61.         mov     cl, 4
  62.         sar     ax, cl
  63.         }
  64. done:
  65.         *expP = _AX;
  66.         return;
  67.  
  68. denormal:
  69. // denormal case a little tricky, so we normalize and try again
  70. asm     {
  71.         FLD     DOUBLE (value)
  72.         FTST
  73.         FSTSW   statword
  74.         FWAIT
  75.         mov     ax, statword
  76.         sahf
  77.         xchg    ax, cx          // convenient 0
  78.         jz      done            // result is +0 or -0
  79.         mov     W0 (statword), 100
  80.         FILD    W0 (statword)
  81.         FXCH
  82.         FSCALE
  83.         FSTP    DOUBLE(value)
  84.         mov     cx, 100 * 10h
  85.         FSTP    st(0)           // discard 100
  86.         }
  87.         goto start;
  88.  
  89. #else   /* not Windows */
  90.  
  91. asm     FLD     DOUBLE (value)
  92.  
  93. asm     LES_    bx, expP
  94. asm     mov     W0 (ES_ [bx]), 0
  95.  
  96. /* if value was +-0, return it */
  97. asm     FTST
  98. asm     FSTSW   statword
  99. asm     FWAIT
  100. asm     mov     ah, BY1(statword)
  101. asm     sahf
  102. asm     jz      done
  103.  
  104. asm     FXTRACT                 /* ST(1) = exponent, (pushed) ST = fraction */
  105. asm     FXCH
  106.  
  107. /*
  108.   The FXTRACT instruction normalizes the fraction 1 bit higher than
  109.   wanted for the definition of frexp() so we need to tweak the result
  110.   by scaling the fraction down and incrementing the exponent.
  111. */
  112.  
  113. asm     FISTP   W0 (ES_ [bx])
  114. asm     FLD1
  115. asm     FCHS
  116. asm     FXCH
  117. asm     FSCALE                  /* fraction scaled as C expects */
  118. asm     inc     W0 (ES_ [bx])   /* exponent biased to match     */
  119. asm     FSTP    ST(1)           /* discard -1, leave fraction as TOS */
  120.  
  121. done:
  122.         return;
  123.  
  124. #endif  /* Windows */
  125.  
  126. }
  127. #pragma warn .rvl
  128.