diff options
Diffstat (limited to 'source/f128_roundToInt.c')
-rw-r--r-- | source/f128_roundToInt.c | 52 |
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; |