📄 softfloat.c
字号:
}/*-------------------------------------------------------------------------------Returns 1 if the single-precision floating-point value `a' is less than orequal to the corresponding value `b', and 0 otherwise. The comparison isperformed according to the IEC/IEEE Standard for Binary Floating-pointArithmetic.-------------------------------------------------------------------------------*/flag float32_le( float32 a, float32 b ){ flag aSign, bSign; if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { float_raise( float_flag_invalid ); return 0; } aSign = extractFloat32Sign( a ); bSign = extractFloat32Sign( b ); if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); return ( a == b ) || ( aSign ^ ( a < b ) );}/*-------------------------------------------------------------------------------Returns 1 if the single-precision floating-point value `a' is less thanthe corresponding value `b', and 0 otherwise. The comparison is performedaccording to the IEC/IEEE Standard for Binary Floating-point Arithmetic.-------------------------------------------------------------------------------*/flag float32_lt( float32 a, float32 b ){ flag aSign, bSign; if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { float_raise( float_flag_invalid ); return 0; } aSign = extractFloat32Sign( a ); bSign = extractFloat32Sign( b ); if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); return ( a != b ) && ( aSign ^ ( a < b ) );}/*-------------------------------------------------------------------------------Returns 1 if the single-precision floating-point value `a' is equal to thecorresponding value `b', and 0 otherwise. The invalid exception is raisedif either operand is a NaN. Otherwise, the comparison is performedaccording to the IEC/IEEE Standard for Binary Floating-point Arithmetic.-------------------------------------------------------------------------------*/flag float32_eq_signaling( float32 a, float32 b ){ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { float_raise( float_flag_invalid ); return 0; } return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );}/*-------------------------------------------------------------------------------Returns 1 if the single-precision floating-point value `a' is less than orequal to the corresponding value `b', and 0 otherwise. Quiet NaNs do notcause an exception. Otherwise, the comparison is performed according to theIEC/IEEE Standard for Binary Floating-point Arithmetic.-------------------------------------------------------------------------------*/flag float32_le_quiet( float32 a, float32 b ){ flag aSign, bSign; //int16 aExp, bExp; if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { float_raise( float_flag_invalid ); } return 0; } aSign = extractFloat32Sign( a ); bSign = extractFloat32Sign( b ); if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); return ( a == b ) || ( aSign ^ ( a < b ) );}/*-------------------------------------------------------------------------------Returns 1 if the single-precision floating-point value `a' is less thanthe corresponding value `b', and 0 otherwise. Quiet NaNs do not cause anexception. Otherwise, the comparison is performed according to the IEC/IEEEStandard for Binary Floating-point Arithmetic.-------------------------------------------------------------------------------*/flag float32_lt_quiet( float32 a, float32 b ){ flag aSign, bSign; if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { float_raise( float_flag_invalid ); } return 0; } aSign = extractFloat32Sign( a ); bSign = extractFloat32Sign( b ); if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); return ( a != b ) && ( aSign ^ ( a < b ) );}/*-------------------------------------------------------------------------------Returns the result of converting the double-precision floating-point value`a' to the 32-bit two's complement integer format. The conversion isperformed according to the IEC/IEEE Standard for Binary Floating-pointArithmetic---which means in particular that the conversion is roundedaccording to the current rounding mode. If `a' is a NaN, the largestpositive integer is returned. Otherwise, if the conversion overflows, thelargest integer with the same sign as `a' is returned.-------------------------------------------------------------------------------*/int32 float64_to_int32( float64 a ){ flag aSign; int16 aExp, shiftCount; bits64 aSig; aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); shiftCount = 0x42C - aExp; if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); return roundAndPackInt32( aSign, aSig );}/*-------------------------------------------------------------------------------Returns the result of converting the double-precision floating-point value`a' to the 32-bit two's complement integer format. The conversion isperformed according to the IEC/IEEE Standard for Binary Floating-pointArithmetic, except that the conversion is always rounded toward zero. If`a' is a NaN, the largest positive integer is returned. Otherwise, if theconversion overflows, the largest integer with the same sign as `a' isreturned.-------------------------------------------------------------------------------*/int32 float64_to_int32_round_to_zero( float64 a ){ flag aSign; int16 aExp, shiftCount; bits64 aSig, savedASig; int32 z; aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); shiftCount = 0x433 - aExp; if ( shiftCount < 21 ) { if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; goto invalid; } else if ( 52 < shiftCount ) { if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; return 0; } aSig |= LIT64( 0x0010000000000000 ); savedASig = aSig; aSig >>= shiftCount; z = aSig; if ( aSign ) z = - z; if ( ( z < 0 ) ^ aSign ) { invalid: float_exception_flags |= float_flag_invalid; return aSign ? 0x80000000 : 0x7FFFFFFF; } if ( ( aSig<<shiftCount ) != savedASig ) { float_exception_flags |= float_flag_inexact; } return z;}/*-------------------------------------------------------------------------------Returns the result of converting the double-precision floating-point value`a' to the 32-bit two's complement unsigned integer format. The conversionis performed according to the IEC/IEEE Standard for Binary Floating-pointArithmetic---which means in particular that the conversion is roundedaccording to the current rounding mode. If `a' is a NaN, the largestpositive integer is returned. Otherwise, if the conversion overflows, thelargest positive integer is returned.-------------------------------------------------------------------------------*/int32 float64_to_uint32( float64 a ){ flag aSign; int16 aExp, shiftCount; bits64 aSig; aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = 0; //extractFloat64Sign( a ); //if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); shiftCount = 0x42C - aExp; if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); return roundAndPackInt32( aSign, aSig );}/*-------------------------------------------------------------------------------Returns the result of converting the double-precision floating-point value`a' to the 32-bit two's complement integer format. The conversion isperformed according to the IEC/IEEE Standard for Binary Floating-pointArithmetic, except that the conversion is always rounded toward zero. If`a' is a NaN, the largest positive integer is returned. Otherwise, if theconversion overflows, the largest positive integer is returned.-------------------------------------------------------------------------------*/int32 float64_to_uint32_round_to_zero( float64 a ){ flag aSign; int16 aExp, shiftCount; bits64 aSig, savedASig; int32 z; aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); shiftCount = 0x433 - aExp; if ( shiftCount < 21 ) { if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; goto invalid; } else if ( 52 < shiftCount ) { if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; return 0; } aSig |= LIT64( 0x0010000000000000 ); savedASig = aSig; aSig >>= shiftCount; z = aSig; if ( aSign ) z = - z; if ( ( z < 0 ) ^ aSign ) { invalid: float_exception_flags |= float_flag_invalid; return aSign ? 0x80000000 : 0x7FFFFFFF; } if ( ( aSig<<shiftCount ) != savedASig ) { float_exception_flags |= float_flag_inexact; } return z;}/*-------------------------------------------------------------------------------Returns the result of converting the double-precision floating-point value`a' to the single-precision floating-point format. The conversion isperformed according to the IEC/IEEE Standard for Binary Floating-pointArithmetic.-------------------------------------------------------------------------------*/float32 float64_to_float32( float64 a ){ flag aSign; int16 aExp; bits64 aSig; bits32 zSig; aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); if ( aExp == 0x7FF ) { if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); return packFloat32( aSign, 0xFF, 0 ); } shift64RightJamming( aSig, 22, &aSig ); zSig = aSig; if ( aExp || zSig ) { zSig |= 0x40000000; aExp -= 0x381; } return roundAndPackFloat32( aSign, aExp, zSig );}#ifdef FLOATX80/*-------------------------------------------------------------------------------Returns the result of converting the double-precision floating-point value`a' to the extended double-precision floating-point format. The conversionis performed according to the IEC/IEEE Standard for Binary Floating-pointArithmetic.-------------------------------------------------------------------------------*/floatx80 float64_to_floatx80( float64 a ){ flag aSign; int16 aExp; bits64 aSig; aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); if ( aExp == 0x7FF ) { if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); normalizeFloat64Subnormal( aSig, &aExp, &aSig ); } return packFloatx80( aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );}#endif/*-------------------------------------------------------------------------------Rounds the double-precision floating-point value `a' to an integer, andreturns the result as a double-precision floating-point value. Theoperation is performed according to the IEC/IEEE Standard for BinaryFloating-point Arithmetic.-------------------------------------------------------------------------------*/float64 float64_round_to_int( float64 a ){ flag aSign; int16 aExp; bits64 lastBitMask, roundBitsMask; int8 roundingMode; float64 z; aExp = extractFloat64Exp( a ); if ( 0x433 <= aExp ) { if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { return propagateFloat64NaN( a, a ); } return a; } if ( aExp <= 0x3FE ) { if ( (bits64) ( a<<1 ) == 0 ) return a; float_exception_flags |= float_flag_inexact; aSign = extractFloat64Sign( a ); switch ( float_rounding_mode ) { case float_round_nearest_even: if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { return packFloat64( aSign, 0x3FF, 0 ); } break; case float_round_d
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -