|
@@ -4,9 +4,8 @@
|
|
|
** Contains: C source code for implementations of floating-point
|
|
|
** functions which round to integral value or format, as
|
|
|
** defined in header <fp.h>. In particular, this file
|
|
|
-** contains implementations of functions rint, nearbyint,
|
|
|
-** rinttol, round, roundtol, trunc, modf and modfl. This file
|
|
|
-** targets PowerPC or Power platforms.
|
|
|
+** contains implementations of functions rinttol, roundtol,
|
|
|
+** modf and modfl. This file targets PowrPC or Power platforms.
|
|
|
**
|
|
|
** Written by: A. Sazegari, Apple AltiVec Group
|
|
|
** Created originally by Jon Okada, Apple Numerics Group
|
|
@@ -66,42 +65,9 @@ typedef union
|
|
|
static const unsigned long int signMask = 0x80000000ul;
|
|
|
static const double twoTo52 = 4503599627370496.0;
|
|
|
static const double doubleToLong = 4503603922337792.0;
|
|
|
-static const DblInHex Huge = {{ 0x7FF00000, 0x00000000 }};
|
|
|
static const DblInHex TOWARDZERO = {{ 0x00000000, 0x00000001 }};
|
|
|
|
|
|
|
|
|
-
|
|
|
-* *
|
|
|
-* The function nearbyint rounds its double argument to integral value *
|
|
|
-* according to the current rounding direction and returns the result in *
|
|
|
-* double format. This function does not signal inexact. *
|
|
|
-* *
|
|
|
-********************************************************************************
|
|
|
-* *
|
|
|
-* This function calls fabs and copysign. *
|
|
|
-* *
|
|
|
-*******************************************************************************/
|
|
|
-
|
|
|
-double nearbyint ( double x )
|
|
|
- {
|
|
|
- double y;
|
|
|
- double OldEnvironment;
|
|
|
-
|
|
|
- y = twoTo52;
|
|
|
-
|
|
|
- asm ("mffs %0" : "=f" (OldEnvironment));
|
|
|
-
|
|
|
- if ( fabs ( x ) >= y )
|
|
|
- return x;
|
|
|
- if ( x < 0 ) y = -y;
|
|
|
- y = ( x + y ) - y;
|
|
|
- if ( y == 0.0 )
|
|
|
- y = copysign ( y, x );
|
|
|
-
|
|
|
- asm ("mtfsf 255,%0" : : "f" ( OldEnvironment ));
|
|
|
- return ( y );
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
* *
|
|
|
* The function rinttol converts its double argument to integral value *
|
|
@@ -195,99 +161,6 @@ long int rinttol ( double x )
|
|
|
return ( ( long ) argument.words.lo );
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-* *
|
|
|
-* The function round rounds its double argument to integral value *
|
|
|
-* according to the "add half to the magnitude and truncate" rounding of *
|
|
|
-* Pascal's Round function and FORTRAN's ANINT function and returns the *
|
|
|
-* result in double format. This function signals inexact if an ordered *
|
|
|
-* return value is not equal to the operand. *
|
|
|
-* *
|
|
|
-*******************************************************************************/
|
|
|
-
|
|
|
-double round ( double x )
|
|
|
- {
|
|
|
- DblInHex argument, OldEnvironment;
|
|
|
- register double y, z;
|
|
|
- register unsigned long int xHead;
|
|
|
- register long int target;
|
|
|
-
|
|
|
- argument.dbl = x;
|
|
|
- xHead = argument.words.hi & 0x7fffffffUL;
|
|
|
- target = ( argument.words.hi < signMask );
|
|
|
-
|
|
|
- if ( xHead < 0x43300000ul )
|
|
|
-
|
|
|
-* Is |x| < 2.0^52? *
|
|
|
-*******************************************************************************/
|
|
|
- {
|
|
|
- if ( xHead < 0x3ff00000ul )
|
|
|
-
|
|
|
-* Is |x| < 1.0? *
|
|
|
-*******************************************************************************/
|
|
|
- {
|
|
|
- asm ("mffs %0" : "=f" (OldEnvironment.dbl));
|
|
|
- if ( xHead < 0x3fe00000ul )
|
|
|
-
|
|
|
-* Is |x| < 0.5? *
|
|
|
-*******************************************************************************/
|
|
|
- {
|
|
|
- if ( ( xHead | argument.words.lo ) != 0ul )
|
|
|
- OldEnvironment.words.lo |= 0x02000000ul;
|
|
|
- asm ("mtfsf 255,%0" : : "f" ( OldEnvironment.dbl ));
|
|
|
- if ( target )
|
|
|
- return ( 0.0 );
|
|
|
- else
|
|
|
- return ( -0.0 );
|
|
|
- }
|
|
|
-
|
|
|
-* Is 0.5 ² |x| < 1.0? *
|
|
|
-*******************************************************************************/
|
|
|
- OldEnvironment.words.lo |= 0x02000000ul;
|
|
|
- asm ("mtfsf 255,%0" : : "f" ( OldEnvironment.dbl ));
|
|
|
- if ( target )
|
|
|
- return ( 1.0 );
|
|
|
- else
|
|
|
- return ( -1.0 );
|
|
|
- }
|
|
|
-
|
|
|
-* Is 1.0 < |x| < 2.0^52? *
|
|
|
-*******************************************************************************/
|
|
|
- if ( target )
|
|
|
- {
|
|
|
- y = ( x + twoTo52 ) - twoTo52;
|
|
|
- if ( y == x )
|
|
|
- return ( x );
|
|
|
- z = x + 0.5;
|
|
|
- y = ( z + twoTo52 ) - twoTo52;
|
|
|
- if ( y > z )
|
|
|
- return ( y - 1.0 );
|
|
|
- else
|
|
|
- return ( y );
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-* Is x < 0? *
|
|
|
-*******************************************************************************/
|
|
|
- else
|
|
|
- {
|
|
|
- y = ( x - twoTo52 ) + twoTo52;
|
|
|
- if ( y == x )
|
|
|
- return ( x );
|
|
|
- z = x - 0.5;
|
|
|
- y = ( z - twoTo52 ) + twoTo52;
|
|
|
- if ( y < z )
|
|
|
- return ( y + 1.0 );
|
|
|
- else
|
|
|
- return ( y );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-* |x| >= 2.0^52 or x is a NaN. *
|
|
|
-*******************************************************************************/
|
|
|
- return ( x );
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
* *
|
|
|
* The function roundtol converts its double argument to integral format *
|
|
@@ -391,73 +264,6 @@ long int roundtol ( double x )
|
|
|
return ( LONG_MIN );
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-* *
|
|
|
-* The function trunc truncates its double argument to integral value *
|
|
|
-* and returns the result in double format. This function signals *
|
|
|
-* inexact if an ordered return value is not equal to the operand. *
|
|
|
-* *
|
|
|
-*******************************************************************************/
|
|
|
-
|
|
|
-double trunc ( double x )
|
|
|
- {
|
|
|
- DblInHex argument,OldEnvironment;
|
|
|
- register double y;
|
|
|
- register unsigned long int xhi;
|
|
|
- register long int target;
|
|
|
-
|
|
|
- argument.dbl = x;
|
|
|
- xhi = argument.words.hi & 0x7fffffffUL;
|
|
|
- target = ( argument.words.hi < signMask );
|
|
|
-
|
|
|
- if ( xhi < 0x43300000ul )
|
|
|
-
|
|
|
-* Is |x| < 2.0^53? *
|
|
|
-*******************************************************************************/
|
|
|
- {
|
|
|
- if ( xhi < 0x3ff00000ul )
|
|
|
-
|
|
|
-* Is |x| < 1.0? *
|
|
|
-*******************************************************************************/
|
|
|
- {
|
|
|
- if ( ( xhi | argument.words.lo ) != 0ul )
|
|
|
- {
|
|
|
- asm ("mffs %0" : "=f" (OldEnvironment.dbl));
|
|
|
- OldEnvironment.words.lo |= 0x02000000ul;
|
|
|
- asm ("mtfsf 255,%0" : : "f" ( OldEnvironment.dbl ));
|
|
|
- }
|
|
|
- if ( target )
|
|
|
- return ( 0.0 );
|
|
|
- else
|
|
|
- return ( -0.0 );
|
|
|
- }
|
|
|
-
|
|
|
-* Is 1.0 < |x| < 2.0^52? *
|
|
|
-*******************************************************************************/
|
|
|
- if ( target )
|
|
|
- {
|
|
|
- y = ( x + twoTo52 ) - twoTo52;
|
|
|
- if ( y > x )
|
|
|
- return ( y - 1.0 );
|
|
|
- else
|
|
|
- return ( y );
|
|
|
- }
|
|
|
-
|
|
|
- else
|
|
|
- {
|
|
|
- y = ( x - twoTo52 ) + twoTo52;
|
|
|
- if ( y < x )
|
|
|
- return ( y + 1.0 );
|
|
|
- else
|
|
|
- return ( y );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-* Is |x| >= 2.0^52 or x is a NaN. *
|
|
|
-*******************************************************************************/
|
|
|
- return ( x );
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
* The modf family of functions separate a floating-point number into its *
|
|
|
* fractional and integral parts, returning the fractional part and writing *
|