fpc.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,417 行 · 第 1/3 页

C
1,417
字号
    } else if( d_isNegZero( src ) ) {
        makeExtNegZero( dst );
    } else {
        parseDouble( *(double*)src, &f, &e );
        f <<= 11;
        makeExtended( (char*)dst, f, e );
        if( d_isNeg( src ) ) {
            eneg( dst, dst );
        }
    }
}

void e2f( void *dst, void *src ) {
    uint64 f;
    int e;
    mpnum temp;

    if( e_isNan( src ) ) {
        *(uint32*)dst = FLOAT_NAN;
    } else if( e_isPosInf( src ) ) {
        *(uint32*)dst = FLOAT_POS_INF;
    } else if( e_isNegInf( src ) ) {
        *(uint32*)dst = FLOAT_NEG_INF;
    } else if( e_isPosZero( src ) ) {
        *(uint32*)dst = FLOAT_POS_ZERO;
    } else if( e_isNegZero( src ) ) {
        *(uint32*)dst = FLOAT_NEG_ZERO;
    } else {
        parseExtended( (char*)src, &f, &e );
        mp_init( &temp, f );
        if( e + float_bias <= 0 && e + float_bias > -24 ) {
            mp_binround( &temp, &temp, 40 - (e + float_bias) + 1 );
            mp_shiftright( &temp, &temp, 40 - (e + float_bias) + 1 );
        } else {
            mp_binround( &temp, &temp, 40 );
            mp_shiftright( &temp, &temp, 40 );
        }
        mp_touint64( &f, &temp );
        makeFloat( (float*)dst, f, e );
        mp_free( &temp );
        if( e_isNeg( src ) ) {
            fneg( dst, dst );
        }
    }
}

void f2e( void *dst, void *src ) {
    uint64 f;
    int e;

    if( f_isNan( src ) ) {
        makeExtNan( dst );
    } else if( f_isPosInf( src ) ) {
        makeExtPosInf( dst );
    } else if( f_isNegInf( src ) ) {
        makeExtNegInf( dst );
    } else if( f_isPosZero( src ) ) {
        makeExtPosZero( dst );
    } else if( f_isNegZero( src ) ) {
        makeExtNegZero( dst );
    } else {
        parseFloat( *(float*)src, &f, &e );
        f <<= 40;
        makeExtended( (char*)dst, f, e );
        if( f_isNeg( src ) ) {
            eneg( dst, dst );
        }
    }
}

void f2i( void *dst, void *src ) {
    uint64 f;
    int e;
    mpnum num;

    if( f_isNan( src ) ) {
        *(int32*)dst = 0;
        return;
    }
    parseFloat( *(float*)src, &f, &e );
    mp_init( &num, f );
    e -= 23;
    if( e > 0 ) {
        mp_shiftleft( &num, &num, e );
    } else if( e < 0 ) {
        mp_shiftright( &num, &num, -e );
    }
    mp_touint64( &f, &num );
    if( f > LONG_MAX ) f = LONG_MAX;
    if( f_isNeg( src ) ) {
        *(int32*)dst = -f;
    } else {
        *(int32*)dst = f;
    }
    mp_free( &num );
}

void i2f( void *dst, void *src ) {
    int32 num = *(int32*)src;
    mpnum n;
    int isNeg = FALSE;
    if( num < 0 ) {
        isNeg = TRUE;
        num = -num;
    }
    mp_init( &n, (uint64) num );
    mp_tofloat( dst, &n );
    if( isNeg ) {
        fneg( dst, dst );
    }
    mp_free( &n );
}

void f2l( void *dst, void *src ) {
    uint64 f;
    int e;
    mpnum num;

    if( f_isNan( src ) ) {
        *(int64*)dst = 0;
        return;
    }
    parseFloat( *(float*)src, &f, &e );
    mp_init( &num, f );
    e -= 23;
    if( e > 0 ) {
        mp_shiftleft( &num, &num, e );
    } else if( e < 0 ) {
        mp_shiftright( &num, &num, -e );
    }
    mp_touint64( &f, &num );
    if( f > LONGLONG_MAX ) f = LONGLONG_MAX;
    if( f_isNeg( src ) ) {
        *(int64*)dst = -f;
    } else {
        *(int64*)dst = f;
    }
    mp_free( &num );
}

void l2f( void *dst, void *src ) {
    int64 num = *(int64*)src;
    mpnum n;
    int isNeg = FALSE;
    if( num < 0 ) {
        isNeg = TRUE;
        num = -num;
    }
    mp_init( &n, (uint64) num );
    mp_tofloat( dst, &n );
    if( isNeg ) {
        fneg( dst, dst );
    }
    mp_free( &n );
}

void d2i( void *dst, void *src ) {
    uint64 f;
    int e;
    mpnum num;

    if( d_isNan( src ) ) {
        *(int32*)dst = 0;
        return;
    }
    parseDouble( *(double*)src, &f, &e );
    mp_init( &num, f );
    e -= 52;
    if( e > 0 ) {
        mp_shiftleft( &num, &num, e );
    } else if( e < 0 ) {
        mp_shiftright( &num, &num, -e );
    }
    mp_touint64( &f, &num );
    if( f > LONG_MAX ) f = LONG_MAX;
    if( d_isNeg( src ) ) {
        *(int32*)dst = -f;
    } else {
        *(int32*)dst = f;
    }
    mp_free( &num );
}

void i2d( void *dst, void *src ) {
    int32 num = *(int32*)src;
    mpnum n;
    int isNeg = FALSE;
    if( num < 0 ) {
        isNeg = TRUE;
        num = -num;
    }
    mp_init( &n, (uint64) num );
    mp_todouble( dst, &n );
    if( isNeg ) {
        dneg( dst, dst );
    }
    mp_free( &n );
}

void d2l( void *dst, void *src ) {
    uint64 f;
    int e;
    mpnum num;

    if( d_isNan( src ) ) {
        *(int64*)dst = 0;
        return;
    }
    parseDouble( *(double*)src, &f, &e );
    mp_init( &num, f );
    e -= 52;
    if( e > 0 ) {
        mp_shiftleft( &num, &num, e );
    } else if( e < 0 ) {
        mp_shiftright( &num, &num, -e );
    }
    mp_touint64( &f, &num );
    if( f > LONGLONG_MAX ) f = LONGLONG_MAX;
    if( d_isNeg( src ) ) {
        *(int64*)dst = -f;
    } else {
        *(int64*)dst = f;
    }
    mp_free( &num );
}

void l2d( void *dst, void *src ) {
    int64 num = *(int64*)src;
    mpnum n;
    int isNeg = FALSE;
    if( num < 0 ) {
        isNeg = TRUE;
        num = -num;
    }
    mp_init( &n, (uint64) num );
    mp_todouble( dst, &n );
    if( isNeg ) {
        dneg( dst, dst );
    }
    mp_free( &n );
}

void e2i( void *dst, void *src ) {
    uint64 f;
    int e;
    mpnum num;

    if( e_isNan( src ) ) {
        *(int32*)dst = 0;
        return;
    }
    parseExtended( (char*)src, &f, &e );
    mp_init( &num, f );
    e -= 63;
    if( e > 0 ) {
        mp_shiftleft( &num, &num, e );
    } else if( e < 0 ) {
        mp_shiftright( &num, &num, -e );
    }
    mp_touint64( &f, &num );
    if( f > LONG_MAX ) f = LONG_MAX;
    if( e_isNeg( src ) ) {
        *(int32*)dst = -f;
    } else {
        *(int32*)dst = f;
    }
    mp_free( &num );
}

void i2e( void *dst, void *src ) {
    int32 num = *(int32*)src;
    mpnum n;
    int isNeg = FALSE;
    if( num < 0 ) {
        isNeg = TRUE;
        num = -num;
    }
    mp_init( &n, (uint64) num );
    mp_toextended( dst, &n );
    if( isNeg ) {
        eneg( dst, dst );
    }
    mp_free( &n );
}

void e2l( void *dst, void *src ) {
    uint64 f;
    int e;
    mpnum num;

    if( e_isNan( src ) ) {
        *(int64*)dst = 0;
        return;
    }
    parseExtended( (char*)src, &f, &e );
    mp_init( &num, f );
    e -= 63;
    if( e > 0 ) {
        mp_shiftleft( &num, &num, e );
    } else if( e < 0 ) {
        mp_shiftright( &num, &num, -e );
    }
    mp_touint64( &f, &num );
    if( f > LONGLONG_MAX ) f = LONGLONG_MAX;
    if( e_isNeg( src ) ) {
        *(int64*)dst = -f;
    } else {
        *(int64*)dst = f;
    }
    mp_free( &num );
}

void l2e( void *dst, void *src ) {
    int64 num = *(int64*)src;
    mpnum n;
    int isNeg = FALSE;
    if( num < 0 ) {
        isNeg = TRUE;
        num = -num;
    }
    mp_init( &n, (uint64) num );
    mp_toextended( dst, &n );
    if( isNeg ) {
        eneg( dst, dst );
    }
    mp_free( &n );
}

int fcmp( void *arg1, void *arg2 )
{
    uint64 f1, f2;
    int e1, e2;
    int isNeg1 = f_isNeg( arg1 );
    int isNeg2 = f_isNeg( arg2 );
    int result = 0;

    /* check for Nan */
    if( f_isNan( arg1 ) || f_isNan( arg2 ) ) {
        return -2;  /* unordered */
    }

    /* check +/-0 == +/-0 */
    if( f_isZero( arg1 ) && f_isZero( arg2 ) ) {
        return 0;
    } else if( f_isZero( arg1 ) ) {
        if( isNeg2 ) return -1;
        else return 1;
    } else if( f_isZero( arg2 ) ) {
        if( isNeg1 ) return 1;
        else return -1;
    }

    /* check sign */
    if( isNeg1 && !isNeg2 ) {
        return 1;
    } else if( !isNeg1 && isNeg2 ) {
        return -1;
    }

    parseFloat( *(float*)arg1, &f1, &e1 );
    parseFloat( *(float*)arg2, &f2, &e2 );

    /* check exponent */
    if( e1 > e2 ) {
        result = -1;
    } else if( e1 < e2 ) {
        result = 1;
    } else {
        /* check mantissa */
        if( f1 > f2 ) {
            result = -1;
        } else if( f1 < f2 ) {
            result = 1;
        } else {
            result = 0;
        }
    }

    /* if values are both negative, switch result */
    if( isNeg1 ) result = -result;

    return result;
}

int dcmp( void *arg1, void *arg2 )
{
    uint64 f1, f2;
    int e1, e2;
    int isNeg1 = d_isNeg( arg1 );
    int isNeg2 = d_isNeg( arg2 );
    int result = 0;

    /* check for Nan */
    if( d_isNan( arg1 ) || d_isNan( arg2 ) ) {
        return -2;  /* unordered */
    }

    /* check +/-0 == +/-0 */
    if( d_isZero( arg1 ) && d_isZero( arg2 ) ) {
        return 0;
    } else if( d_isZero( arg1 ) ) {
        if( isNeg2 ) return -1;
        else return 1;
    } else if( d_isZero( arg2 ) ) {
        if( isNeg1 ) return 1;
        else return -1;
    }

    /* check sign */
    if( isNeg1 && !isNeg2 ) {
        return 1;
    } else if( !isNeg1 && isNeg2 ) {
        return -1;
    }

    parseDouble( *(double*)arg1, &f1, &e1 );
    parseDouble( *(double*)arg2, &f2, &e2 );

    /* check exponent */
    if( e1 > e2 ) {
        result = -1;
    } else if( e1 < e2 ) {
        result = 1;
    } else {
        /* check mantissa */
        if( f1 > f2 ) {
            result = -1;
        } else if( f1 < f2 ) {
            result = 1;
        } else {
            result = 0;
        }
    }

    /* if values are both negative, switch result */
    if( isNeg1 ) result = -result;

    return result;
}
#endif

#ifdef TEST

void OutputFloatInHex( void *fl )
{
    char *flt = (char*)fl;
    int i;
    printf( "0x" );
    for( i = 3; i >= 0; i-- ) {
        printf( "%02x", flt[i] );
    }
    printf( "\n" );
}

void OutputDoubleInHex( void *db )
{
    char *dbl = (char*)db;
    int i;
    printf( "0x" );
    for( i = 7; i >= 0; i-- ) {
        printf( "%02x", dbl[i] );
    }
    printf( "\n" );
}

main()
{
}

#endif /* ifdef TEST */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?