home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------
- * filename - frexp.cas
- *
- * function(s)
- * frexp - splits a double number into mantissa and exponent
- *-----------------------------------------------------------------------*/
-
- /*
- * C/C++ Run Time Library - Version 5.0
- *
- * Copyright (c) 1987, 1992 by Borland International
- * All Rights Reserved.
- *
- */
-
-
- #pragma inline
- #include <asmrules.h>
-
- #include <_math.h>
- #include <math.h>
-
- /*--------------------------------------------------------------------------*
-
- Name frexp - splits a double number into mantissa and exponent
-
- Usage double frexp(double value, int *expP);
-
- Prototype in math.h
-
- Description Split a floating point number into its exponent and
- fractional parts, with the exponent placed into *expP, and
- the fraction is the function return value.
-
- Return value frexp returns value - (*expP = chop (value));
-
- *---------------------------------------------------------------------------*/
- #pragma warn -rvl
-
- double _FARFUNC frexp( double value, int *expP )
- {
- volatile unsigned statword;
-
- #ifdef _Windows
-
- // The Microsoft FP emulator does not support the FXTRACT instruction.
-
- _CX = 0;
- start:
- asm {
- mov ax, value[6]
- mov dx, ax
- and ax, 7FF0h
- jz denormal
- sub dx, ax
- sub ax, 3FE0h
- or dx, 3FE0h
- mov value[6], dx
- FLD DOUBLE (value)
- sub ax, cx // possible denormal adjustment
- mov cl, 4
- sar ax, cl
- }
- done:
- *expP = _AX;
- return;
-
- denormal:
- // denormal case a little tricky, so we normalize and try again
- asm {
- FLD DOUBLE (value)
- FTST
- FSTSW statword
- FWAIT
- mov ax, statword
- sahf
- xchg ax, cx // convenient 0
- jz done // result is +0 or -0
- mov W0 (statword), 100
- FILD W0 (statword)
- FXCH
- FSCALE
- FSTP DOUBLE(value)
- mov cx, 100 * 10h
- FSTP st(0) // discard 100
- }
- goto start;
-
- #else /* not Windows */
-
- asm FLD DOUBLE (value)
-
- asm LES_ bx, expP
- asm mov W0 (ES_ [bx]), 0
-
- /* if value was +-0, return it */
- asm FTST
- asm FSTSW statword
- asm FWAIT
- asm mov ah, BY1(statword)
- asm sahf
- asm jz done
-
- asm FXTRACT /* ST(1) = exponent, (pushed) ST = fraction */
- asm FXCH
-
- /*
- The FXTRACT instruction normalizes the fraction 1 bit higher than
- wanted for the definition of frexp() so we need to tweak the result
- by scaling the fraction down and incrementing the exponent.
- */
-
- asm FISTP W0 (ES_ [bx])
- asm FLD1
- asm FCHS
- asm FXCH
- asm FSCALE /* fraction scaled as C expects */
- asm inc W0 (ES_ [bx]) /* exponent biased to match */
- asm FSTP ST(1) /* discard -1, leave fraction as TOS */
-
- done:
- return;
-
- #endif /* Windows */
-
- }
- #pragma warn .rvl
-