aboutsummaryrefslogtreecommitdiff
path: root/source/f128_roundToInt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/f128_roundToInt.c')
-rw-r--r--source/f128_roundToInt.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/source/f128_roundToInt.c b/source/f128_roundToInt.c
index 0f1f07e..96ae30e 100644
--- a/source/f128_roundToInt.c
+++ b/source/f128_roundToInt.c
@@ -2,7 +2,7 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
-Package, Release 3d, by John R. Hauser.
+Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
California. All rights reserved.
@@ -48,8 +48,9 @@ float128_t
uint_fast64_t uiA64, uiA0;
int_fast32_t exp;
struct uint128 uiZ;
- uint_fast64_t lastBitMask, roundBitsMask;
+ uint_fast64_t lastBitMask0, roundBitsMask;
bool roundNearEven;
+ uint_fast64_t lastBitMask64;
union ui128_f128 uZ;
/*------------------------------------------------------------------------
@@ -72,8 +73,8 @@ float128_t
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
- lastBitMask = (uint_fast64_t) 2<<(0x406E - exp);
- roundBitsMask = lastBitMask - 1;
+ lastBitMask0 = (uint_fast64_t) 2<<(0x406E - exp);
+ roundBitsMask = lastBitMask0 - 1;
uiZ.v64 = uiA64;
uiZ.v0 = uiA0;
roundNearEven = (roundingMode == softfloat_round_near_even);
@@ -89,9 +90,9 @@ float128_t
}
}
} else {
- uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, lastBitMask>>1 );
- if ( roundNearEven && ! (uiZ.v0 & roundBitsMask) ) {
- uiZ.v0 &= ~lastBitMask;
+ uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, lastBitMask0>>1 );
+ if ( roundNearEven && !(uiZ.v0 & roundBitsMask) ) {
+ uiZ.v0 &= ~lastBitMask0;
}
}
} else if (
@@ -102,19 +103,18 @@ float128_t
uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, roundBitsMask );
}
uiZ.v0 &= ~roundBitsMask;
+ lastBitMask64 = !lastBitMask0;
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if ( exp < 0x3FFF ) {
- if ( ! ((uiA64 & UINT64_C( 0x7FFFFFFFFFFFFFFF )) | uiA0) ) {
- return a;
- }
+ if ( !((uiA64 & UINT64_C( 0x7FFFFFFFFFFFFFFF )) | uiA0) ) return a;
if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;
uiZ.v64 = uiA64 & packToF128UI64( 1, 0, 0 );
uiZ.v0 = 0;
switch ( roundingMode ) {
case softfloat_round_near_even:
- if ( ! (fracF128UI64( uiA64 ) | uiA0) ) break;
+ if ( !(fracF128UI64( uiA64 ) | uiA0) ) break;
case softfloat_round_near_maxMag:
if ( exp == 0x3FFE ) uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 );
break;
@@ -122,8 +122,13 @@ float128_t
if ( uiZ.v64 ) uiZ.v64 = packToF128UI64( 1, 0x3FFF, 0 );
break;
case softfloat_round_max:
- if ( ! uiZ.v64 ) uiZ.v64 = packToF128UI64( 0, 0x3FFF, 0 );
+ if ( !uiZ.v64 ) uiZ.v64 = packToF128UI64( 0, 0x3FFF, 0 );
+ break;
+#ifdef SOFTFLOAT_ROUND_ODD
+ case softfloat_round_odd:
+ uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 );
break;
+#endif
}
goto uiZ;
}
@@ -131,14 +136,14 @@ float128_t
*--------------------------------------------------------------------*/
uiZ.v64 = uiA64;
uiZ.v0 = 0;
- lastBitMask = (uint_fast64_t) 1<<(0x402F - exp);
- roundBitsMask = lastBitMask - 1;
+ lastBitMask64 = (uint_fast64_t) 1<<(0x402F - exp);
+ roundBitsMask = lastBitMask64 - 1;
if ( roundingMode == softfloat_round_near_maxMag ) {
- uiZ.v64 += lastBitMask>>1;
+ uiZ.v64 += lastBitMask64>>1;
} else if ( roundingMode == softfloat_round_near_even ) {
- uiZ.v64 += lastBitMask>>1;
- if ( ! ((uiZ.v64 & roundBitsMask) | uiA0) ) {
- uiZ.v64 &= ~lastBitMask;
+ uiZ.v64 += lastBitMask64>>1;
+ if ( !((uiZ.v64 & roundBitsMask) | uiA0) ) {
+ uiZ.v64 &= ~lastBitMask64;
}
} else if (
roundingMode
@@ -148,9 +153,16 @@ float128_t
uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask;
}
uiZ.v64 &= ~roundBitsMask;
+ lastBitMask0 = 0;
}
- if ( exact && ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) ) {
- softfloat_exceptionFlags |= softfloat_flag_inexact;
+ if ( (uiZ.v64 != uiA64) || (uiZ.v0 != uiA0) ) {
+#ifdef SOFTFLOAT_ROUND_ODD
+ if ( roundingMode == softfloat_round_odd ) {
+ uiZ.v64 |= lastBitMask64;
+ uiZ.v0 |= lastBitMask0;
+ }
+#endif
+ if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;
}
uiZ:
uZ.ui = uiZ;