int_fast32_t f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact ) { union ui32_f32 uA; uint_fast32_t uiA; bool sign; int_fast16_t exp; uint_fast32_t sig; uint_fast64_t sig64; int_fast16_t shiftCount; uA.f = a; uiA = uA.ui; sign = signF32UI( uiA ); exp = expF32UI( uiA ); sig = fracF32UI( uiA ); if ( (exp == 0xFF) && sig ) sign = 0; if ( exp ) sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<32; shiftCount = 0xAF - exp; if ( 0 < shiftCount ) { sig64 = softfloat_shiftRightJam64( sig64, shiftCount ); } return softfloat_roundPackToI32( sign, sig64, roundingMode, exact ); }
int_fast64_t f16_to_i64( float16_t a, uint_fast8_t roundingMode, bool exact ) { union ui16_f16 uA; uint_fast16_t uiA; bool sign; int_fast8_t exp; uint_fast16_t frac; int_fast32_t sig32; int_fast8_t shiftDist; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF16UI( uiA ); exp = expF16UI( uiA ); frac = fracF16UI( uiA ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp == 0x1F ) { softfloat_raiseFlags( softfloat_flag_invalid ); return frac ? i64_fromNaN : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ sig32 = frac; if ( exp ) { sig32 |= 0x0400; shiftDist = exp - 0x19; if ( 0 <= shiftDist ) { sig32 <<= shiftDist; return sign ? -sig32 : sig32; } shiftDist = exp - 0x0D; if ( 0 < shiftDist ) sig32 <<= shiftDist; } return softfloat_roundPackToI32( sign, (uint_fast32_t) sig32, roundingMode, exact ); }
int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t sig; int_fast16_t shiftCount; uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); if ( (exp == 0x7FF) && sig ) sign = 0; if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); shiftCount = 0x42C - exp; if ( 0 < shiftCount ) sig = softfloat_shiftRightJam64( sig, shiftCount ); return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); }
int_fast32_t extF80_to_i32( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) { union { struct extFloat80M s; extFloat80_t f; } uA; uint_fast16_t uiA64; bool sign; int_fast32_t exp; uint_fast64_t sig; int_fast32_t shiftCount; uA.f = a; uiA64 = uA.s.signExp; sign = signExtF80UI64( uiA64 ); exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; if ( (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) sign = 0; shiftCount = 0x4037 - exp; if ( shiftCount <= 0 ) shiftCount = 1; sig = softfloat_shiftRightJam64( sig, shiftCount ); return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); }
int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t sig; int_fast16_t shiftDist; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ #if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) if ( (exp == 0x7FF) && sig ) { #if (i32_fromNaN == i32_fromPosOverflow) sign = 0; #elif (i32_fromNaN == i32_fromNegOverflow) sign = 1; #else softfloat_raiseFlags( softfloat_flag_invalid ); return i32_fromNaN; #endif } #endif /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); shiftDist = 0x42C - exp; if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); }