aboutsummaryrefslogtreecommitdiff
path: root/source/s_roundToI64.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/s_roundToI64.c')
-rw-r--r--source/s_roundToI64.c50
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;
/*------------------------------------------------------------------------