fold.cpp
/*
 * Returns the result of subtracting the absolute values of `a' and `b'. If the
 * sign `sign_z' is one, the difference is negated before being returned. The
 * sign is ignored if the result is a NaN.
 */
Returns the result of subtracting the absolute values of `a' and `b'. If the
sign `sign_z' is one, the difference is negated before being returned. The
sign is ignored if the result is a NaN.
Returns the result of subtracting the absolute values of ` a ' and ` b ' . If the sign ` sign_z ' is one the difference is negated before being returned . The sign is ignored if the result is a NaN .
static sfloat_t sfloat_sub_impl(sfloat_state_t *state, sfloat_t a, sfloat_t b, bool sign_z) {
    int16_t  exp_a = SFLOAT_EXTRACT_EXP(a);
    int16_t  exp_b = SFLOAT_EXTRACT_EXP(b);
    int16_t  exp_z = 0;
    int16_t  exp_d = exp_a - exp_b;
    uint32_t sig_a = SFLOAT_EXTRACT_FRAC(a) << 7;
    uint32_t sig_b = SFLOAT_EXTRACT_FRAC(b) << 7;
    uint32_t sig_z = 0;
    if (0 < exp_d) goto exp_greater_a;
    if (exp_d < 0) goto exp_greater_b;
    if (exp_a == 0xFF) {
        if (sig_a | sig_b)
            return sfloat_propagate_nan(state, a, b);
        SFLOAT_RAISE(state, SFLOAT_INVALID);
        return SFLOAT_NAN;
    }
    if (exp_a == 0)
        exp_a = exp_b = 1;
    if (sig_b < sig_a) goto greater_a;
    if (sig_a < sig_b) goto greater_b;
    return SFLOAT_PACK(state->roundingmode == SFLOAT_ROUND_DOWN, 0, 0);
exp_greater_b:
    if (exp_b == 0xFF)
        return (sig_b) ? sfloat_propagate_nan(state, a, b) : SFLOAT_PACK(sign_z ^ 1, 0xFF, 0);
    if (exp_a == 0)
        ++exp_d;
    else
        sig_a |= 0x40000000;
    SFLOAT_SHIFT(32, sig_a, -exp_d, &sig_a);
    sig_b |= 0x40000000;
greater_b:
    sig_z = sig_b - sig_a;
    exp_z = exp_b;
    sign_z ^= 1;
    goto end;
exp_greater_a:
    if (exp_a == 0xFF)
        return (sig_a) ? sfloat_propagate_nan(state, a, b) : a;
    if (exp_b == 0)
        --exp_d;
    else
        sig_b |= 0x40000000;
    SFLOAT_SHIFT(32, sig_b, exp_d, &sig_b);
    sig_a |= 0x40000000;
greater_a:
    sig_z = sig_a - sig_b;
    exp_z = exp_a;
end:
    --exp_z;
    return SFLOAT_PACK_normal(state, sign_z, exp_z, sig_z);
}
static sfloat_t sfloat_sub_impl ( sfloat_state_t * state , sfloat_t a , sfloat_t b , bool sign_z ) { int16_t exp_a = SFLOAT_EXTRACT_EXP ( a ) ; int16_t exp_b = SFLOAT_EXTRACT_EXP ( b ) ; int16_t exp_z = 0 ; int16_t exp_d = exp_a - exp_b ; uint32_t sig_a = SFLOAT_EXTRACT_FRAC ( a ) << 7 ; uint32_t sig_b = SFLOAT_EXTRACT_FRAC ( b ) << 7 ; uint32_t sig_z = 0 ; if ( 0 < exp_d ) goto exp_greater_a ; if ( exp_d < 0 ) goto exp_greater_b ; if ( exp_a == 0xFF ) { if ( sig_a | sig_b ) return sfloat_propagate_nan ( state , a , b ) ; SFLOAT_RAISE ( state , SFLOAT_INVALID ) ; return SFLOAT_NAN ; } if ( exp_a == 0 ) exp_a = exp_b = 1 ; if ( sig_b < sig_a ) goto greater_a ; if ( sig_a < sig_b ) goto greater_b ; return SFLOAT_PACK ( state -> roundingmode == SFLOAT_ROUND_DOWN , 0 , 0 ) ; exp_greater_b : if ( exp_b == 0xFF ) return ( sig_b ) ? sfloat_propagate_nan ( state , a , b ) : SFLOAT_PACK ( sign_z ^ 1 , 0xFF , 0 ) ; if ( exp_a == 0 ) ++ exp_d ; else sig_a |= 0x40000000 ; SFLOAT_SHIFT ( 32 , sig_a , - exp_d , & sig_a ) ; sig_b |= 0x40000000 ; greater_b : sig_z = sig_b - sig_a ; exp_z = exp_b ; sign_z ^= 1 ; goto end ; exp_greater_a : if ( exp_a == 0xFF ) return ( sig_a ) ? sfloat_propagate_nan ( state , a , b ) : a ; if ( exp_b == 0 ) -- exp_d ; else sig_b |= 0x40000000 ; SFLOAT_SHIFT ( 32 , sig_b , exp_d , & sig_b ) ; sig_a |= 0x40000000 ; greater_a : sig_z = sig_a - sig_b ; exp_z = exp_a ; end : -- exp_z ; return SFLOAT_PACK_normal ( state , sign_z , exp_z , sig_z ) ; }
Returns the result of subtracting the absolute values of `a' and `b'.
Returns the result of subtracting the absolute values of ` a ' and ` b ' .