diff options
Diffstat (limited to 'source/s_roundToI64.c')
-rw-r--r-- | source/s_roundToI64.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/source/s_roundToI64.c b/source/s_roundToI64.c index fcddbc2..d1e9d27 100644 --- a/source/s_roundToI64.c +++ b/source/s_roundToI64.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, 2015, 2016, 2017 The Regents of the University of California. All rights reserved. @@ -50,33 +50,45 @@ int_fast64_t bool exact ) { - bool roundNearEven, doIncrement; union { uint64_t ui; int64_t i; } uZ; int_fast64_t z; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - roundNearEven = (roundingMode == softfloat_round_near_even); - doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - if ( doIncrement ) { - ++sig; - if ( ! sig ) goto invalid; - sig &= - ~(uint_fast64_t) - (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - & roundNearEven); + if ( + (roundingMode == softfloat_round_near_maxMag) + || (roundingMode == softfloat_round_near_even) + ) { + if ( UINT64_C( 0x8000000000000000 ) <= sigExtra ) goto increment; + } else { + if ( + sigExtra + && (sign + ? (roundingMode == softfloat_round_min) +#ifdef SOFTFLOAT_ROUND_ODD + || (roundingMode == softfloat_round_odd) +#endif + : (roundingMode == softfloat_round_max)) + ) { + increment: + ++sig; + if ( !sig ) goto invalid; + if ( + (sigExtra == UINT64_C( 0x8000000000000000 )) + && (roundingMode == softfloat_round_near_even) + ) { + sig &= ~(uint_fast64_t) 1; + } + } } uZ.ui = sign ? -sig : sig; z = uZ.i; if ( z && ((z < 0) ^ sign) ) goto invalid; - if ( exact && sigExtra ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; + if ( sigExtra ) { +#ifdef SOFTFLOAT_ROUND_ODD + if ( roundingMode == softfloat_round_odd ) z |= 1; +#endif + if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; /*------------------------------------------------------------------------ |