float32_t f64_to_f32( float64_t a ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t sig; uint_fast32_t uiZ, sig32; union ui32_f32 uZ; uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); if ( exp == 0x7FF ) { uiZ = sig ? softfloat_commonNaNToF32UI( softfloat_f64UIToCommonNaN( uiA ) ) : packToF32UI( sign, 0xFF, 0 ); goto uiZ; } sig32 = softfloat_shortShift64RightJam( sig, 22 ); if ( ! ( exp | sig32 ) ) { uiZ = packToF32UI( sign, 0, 0 ); goto uiZ; } return softfloat_roundPackToF32( sign, exp - 0x381, sig32 | 0x40000000 ); uiZ: uZ.ui = uiZ; return uZ.f; }
void f64_to_f128M( float64_t a, float128_t *zPtr ) { uint32_t *zWPtr; union ui64_f64 uA; uint64_t uiA; bool sign; int_fast16_t exp; uint64_t sig; struct commonNaN commonNaN; uint32_t uiZ96; struct exp16_sig64 normExpSig; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zWPtr = (uint32_t *) zPtr; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zWPtr[indexWord( 4, 0 )] = 0; if ( exp == 0x7FF ) { if ( sig ) { softfloat_f64UIToCommonNaN( uiA, &commonNaN ); softfloat_commonNaNToF128M( &commonNaN, zWPtr ); return; } uiZ96 = packToF128UI96( sign, 0x7FFF, 0 ); goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! exp ) { if ( ! sig ) { uiZ96 = packToF128UI96( sign, 0, 0 ); goto uiZ; } normExpSig = softfloat_normSubnormalF64Sig( sig ); exp = normExpSig.exp - 1; sig = normExpSig.sig; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zWPtr[indexWord( 4, 1 )] = (uint32_t) sig<<28; sig >>= 4; zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, exp + 0x3C00, sig>>32 ); zWPtr[indexWord( 4, 2 )] = sig; return; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiZ: zWPtr[indexWord( 4, 3 )] = uiZ96; zWPtr[indexWord( 4, 2 )] = 0; zWPtr[indexWord( 4, 1 )] = 0; }
extFloat80_t f64_to_extF80( float64_t a ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t frac; struct commonNaN commonNaN; struct uint128 uiZ; uint_fast16_t uiZ64; uint_fast64_t uiZ0; struct exp16_sig64 normExpSig; union { struct extFloat80M s; extFloat80_t f; } uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); frac = fracF64UI( uiA ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp == 0x7FF ) { if ( frac ) { softfloat_f64UIToCommonNaN( uiA, &commonNaN ); uiZ = softfloat_commonNaNToExtF80UI( &commonNaN ); uiZ64 = uiZ.v64; uiZ0 = uiZ.v0; } else { uiZ64 = packToExtF80UI64( sign, 0x7FFF ); uiZ0 = UINT64_C( 0x8000000000000000 ); } goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! exp ) { if ( ! frac ) { uiZ64 = packToExtF80UI64( sign, 0 ); uiZ0 = 0; goto uiZ; } normExpSig = softfloat_normSubnormalF64Sig( frac ); exp = normExpSig.exp; frac = normExpSig.sig; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiZ64 = packToExtF80UI64( sign, exp + 0x3C00 ); uiZ0 = (frac | UINT64_C( 0x0010000000000000 ))<<11; uiZ: uZ.s.signExp = uiZ64; uZ.s.signif = uiZ0; return uZ.f; }
void f64_to_extF80M( float64_t a, extFloat80_t *zPtr ) { struct extFloat80M *zSPtr; union ui64_f64 uA; uint64_t uiA; bool sign; int_fast16_t exp; uint64_t frac; struct commonNaN commonNaN; uint_fast16_t uiZ64; uint64_t uiZ0; struct exp16_sig64 normExpSig; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zSPtr = (struct extFloat80M *) zPtr; uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); frac = fracF64UI( uiA ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp == 0x7FF ) { if ( frac ) { softfloat_f64UIToCommonNaN( uiA, &commonNaN ); softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); return; } uiZ64 = packToExtF80UI64( sign, 0x7FFF ); uiZ0 = UINT64_C( 0x8000000000000000 ); goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! exp ) { if ( ! frac ) { uiZ64 = packToExtF80UI64( sign, 0 ); uiZ0 = 0; goto uiZ; } normExpSig = softfloat_normSubnormalF64Sig( frac ); exp = normExpSig.exp; frac = normExpSig.sig; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiZ64 = packToExtF80UI64( sign, exp + 0x3C00 ); uiZ0 = UINT64_C( 0x8000000000000000 ) | frac<<11; uiZ: zSPtr->signExp = uiZ64; zSPtr->signif = uiZ0; }
float128_t f64_to_f128( float64_t a ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t sig; struct commonNaN commonNaN; struct uint128 uiZ; struct exp16_sig64 normExpSig; struct uint128 sig128; union ui128_f128 uZ; uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); if ( exp == 0x7FF ) { if ( sig ) { softfloat_f64UIToCommonNaN( uiA, &commonNaN ); uiZ = softfloat_commonNaNToF128UI( &commonNaN ); } else { uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 ); uiZ.v0 = 0; } goto uiZ; } if ( ! exp ) { if ( ! sig ) { uiZ.v64 = packToF128UI64( sign, 0, 0 ); uiZ.v0 = 0; goto uiZ; } normExpSig = softfloat_normSubnormalF64Sig( sig ); exp = normExpSig.exp - 1; sig = normExpSig.sig; } sig128 = softfloat_shortShiftLeft128( 0, sig, 60 ); uiZ.v64 = packToF128UI64( sign, exp + 0x3C00, sig128.v64 ); uiZ.v0 = sig128.v0; uiZ: uZ.ui = uiZ; return uZ.f; }
float16_t f64_to_f16( float64_t a ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t frac; struct commonNaN commonNaN; uint_fast16_t uiZ, frac16; union ui16_f16 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); frac = fracF64UI( uiA ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp == 0x7FF ) { if ( frac ) { softfloat_f64UIToCommonNaN( uiA, &commonNaN ); uiZ = softfloat_commonNaNToF16UI( &commonNaN ); } else { uiZ = packToF16UI( sign, 0x1F, 0 ); } goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ frac16 = softfloat_shortShiftRightJam64( frac, 38 ); if ( ! (exp | frac16) ) { uiZ = packToF16UI( sign, 0, 0 ); goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ return softfloat_roundPackToF16( sign, exp - 0x3F1, frac16 | 0x4000 ); uiZ: uZ.ui = uiZ; return uZ.f; }