📄 softfloat.java
字号:
// }// if ( bExp == 0 ) {// if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );// normalizeFloat32Subnormal( bSig, &bExp, &bSig );// }// zExp = aExp + bExp - 0x7F;// aSig = ( aSig | 0x00800000 )<<7;// bSig = ( bSig | 0x00800000 )<<8;// mul32To64( aSig, bSig, &zSig0, &zSig1 );// zSig0 |= ( zSig1 != 0 );// if ( 0 <= (sbits32) ( zSig0<<1 ) ) {// zSig0 <<= 1;// --zExp;// }// return roundAndPackFloat32( zSign, zExp, zSig0 );////}/////*----------------------------------------------------------------------------//| Returns the result of dividing the single-precision floating-point value `a'//| by the corresponding value `b'. The operation is performed according to the//| IEC/IEEE Standard for Binary Floating-Point Arithmetic.//*----------------------------------------------------------------------------*/////float32 float32_div( float32 a, float32 b )//{// flag aSign, bSign, zSign;// int16 aExp, bExp, zExp;// bits32 aSig, bSig, zSig, rem0, rem1, term0, term1;//// aSig = extractFloat32Frac( a );// aExp = extractFloat32Exp( a );// aSign = extractFloat32Sign( a );// bSig = extractFloat32Frac( b );// bExp = extractFloat32Exp( b );// bSign = extractFloat32Sign( b );// zSign = aSign ^ bSign;// if ( aExp == 0xFF ) {// if ( aSig ) return propagateFloat32NaN( a, b );// if ( bExp == 0xFF ) {// if ( bSig ) return propagateFloat32NaN( a, b );// float_raise( float_flag_invalid );// return float32_default_nan;// }// return packFloat32( zSign, 0xFF, 0 );// }// if ( bExp == 0xFF ) {// if ( bSig ) return propagateFloat32NaN( a, b );// return packFloat32( zSign, 0, 0 );// }// if ( bExp == 0 ) {// if ( bSig == 0 ) {// if ( ( aExp | aSig ) == 0 ) {// float_raise( float_flag_invalid );// return float32_default_nan;// }// float_raise( float_flag_divbyzero );// return packFloat32( zSign, 0xFF, 0 );// }// normalizeFloat32Subnormal( bSig, &bExp, &bSig );// }// if ( aExp == 0 ) {// if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );// normalizeFloat32Subnormal( aSig, &aExp, &aSig );// }// zExp = aExp - bExp + 0x7D;// aSig = ( aSig | 0x00800000 )<<7;// bSig = ( bSig | 0x00800000 )<<8;// if ( bSig <= ( aSig + aSig ) ) {// aSig >>= 1;// ++zExp;// }// zSig = estimateDiv64To32( aSig, 0, bSig );// if ( ( zSig & 0x3F ) <= 2 ) {// mul32To64( bSig, zSig, &term0, &term1 );// sub64( aSig, 0, term0, term1, &rem0, &rem1 );// while ( (sbits32) rem0 < 0 ) {// --zSig;// add64( rem0, rem1, 0, bSig, &rem0, &rem1 );// }// zSig |= ( rem1 != 0 );// }// return roundAndPackFloat32( zSign, zExp, zSig );////}/////*----------------------------------------------------------------------------//| Returns the remainder of the single-precision floating-point value `a'//| with respect to the corresponding value `b'. The operation is performed//| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.//*----------------------------------------------------------------------------*/////float32 float32_rem( float32 a, float32 b )//{// flag aSign, bSign, zSign;// int16 aExp, bExp, expDiff;// bits32 aSig, bSig, q, allZero, alternateASig;// sbits32 sigMean;//// aSig = extractFloat32Frac( a );// aExp = extractFloat32Exp( a );// aSign = extractFloat32Sign( a );// bSig = extractFloat32Frac( b );// bExp = extractFloat32Exp( b );// bSign = extractFloat32Sign( b );// if ( aExp == 0xFF ) {// if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {// return propagateFloat32NaN( a, b );// }// float_raise( float_flag_invalid );// return float32_default_nan;// }// if ( bExp == 0xFF ) {// if ( bSig ) return propagateFloat32NaN( a, b );// return a;// }// if ( bExp == 0 ) {// if ( bSig == 0 ) {// float_raise( float_flag_invalid );// return float32_default_nan;// }// normalizeFloat32Subnormal( bSig, &bExp, &bSig );// }// if ( aExp == 0 ) {// if ( aSig == 0 ) return a;// normalizeFloat32Subnormal( aSig, &aExp, &aSig );// }// expDiff = aExp - bExp;// aSig = ( aSig | 0x00800000 )<<8;// bSig = ( bSig | 0x00800000 )<<8;// if ( expDiff < 0 ) {// if ( expDiff < -1 ) return a;// aSig >>= 1;// }// q = ( bSig <= aSig );// if ( q ) aSig -= bSig;// expDiff -= 32;// while ( 0 < expDiff ) {// q = estimateDiv64To32( aSig, 0, bSig );// q = ( 2 < q ) ? q - 2 : 0;// aSig = - ( ( bSig>>2 ) * q );// expDiff -= 30;// }// expDiff += 32;// if ( 0 < expDiff ) {// q = estimateDiv64To32( aSig, 0, bSig );// q = ( 2 < q ) ? q - 2 : 0;// q >>= 32 - expDiff;// bSig >>= 2;// aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;// }// else {// aSig >>= 2;// bSig >>= 2;// }// do {// alternateASig = aSig;// ++q;// aSig -= bSig;// } while ( 0 <= (sbits32) aSig );// sigMean = aSig + alternateASig;// if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {// aSig = alternateASig;// }// zSign = ( (sbits32) aSig < 0 );// if ( zSign ) aSig = - aSig;// return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );////}/////*----------------------------------------------------------------------------//| Returns the square root of the single-precision floating-point value `a'.//| The operation is performed according to the IEC/IEEE Standard for Binary//| Floating-Point Arithmetic.//*----------------------------------------------------------------------------*/////float32 float32_sqrt( float32 a )//{// flag aSign;// int16 aExp, zExp;// bits32 aSig, zSig, rem0, rem1, term0, term1;//// aSig = extractFloat32Frac( a );// aExp = extractFloat32Exp( a );// aSign = extractFloat32Sign( a );// if ( aExp == 0xFF ) {// if ( aSig ) return propagateFloat32NaN( a, 0 );// if ( ! aSign ) return a;// float_raise( float_flag_invalid );// return float32_default_nan;// }// if ( aSign ) {// if ( ( aExp | aSig ) == 0 ) return a;// float_raise( float_flag_invalid );// return float32_default_nan;// }// if ( aExp == 0 ) {// if ( aSig == 0 ) return 0;// normalizeFloat32Subnormal( aSig, &aExp, &aSig );// }// zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;// aSig = ( aSig | 0x00800000 )<<8;// zSig = estimateSqrt32( aExp, aSig ) + 2;// if ( ( zSig & 0x7F ) <= 5 ) {// if ( zSig < 2 ) {// zSig = 0x7FFFFFFF;// goto roundAndPack;// }// else {// aSig >>= aExp & 1;// mul32To64( zSig, zSig, &term0, &term1 );// sub64( aSig, 0, term0, term1, &rem0, &rem1 );// while ( (sbits32) rem0 < 0 ) {// --zSig;// shortShift64Left( 0, zSig, 1, &term0, &term1 );// term1 |= 1;// add64( rem0, rem1, term0, term1, &rem0, &rem1 );// }// zSig |= ( ( rem0 | rem1 ) != 0 );// }// }// shift32RightJamming( zSig, 1, &zSig );// roundAndPack:// return roundAndPackFloat32( 0, zExp, zSig );////}///*----------------------------------------------------------------------------| Returns 1 if the single-precision floating-point value `a' is greater to| the corresponding value `b', -1 if smaller and 0 if equal. The comparison is performed| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.| NaN resturns 1 or -1 depending on cmpg of cmpl.*----------------------------------------------------------------------------*/public static int float32_cmpg(int a, int b) { // if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) // || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { if ((((a>>>23) == 0xFF ) && ((a & 0x007FFFFF)!=0)) || (((b>>>23) == 0xFF ) && ((b & 0x007FFFFF)!=0))) { return 1; // one is NaN } return float32_cmp(a, b);}public static int float32_cmpl(int a, int b) { // if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) // || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { if ((((a>>>23) == 0xFF ) && ((a & 0x007FFFFF)!=0)) || (((b>>>23) == 0xFF ) && ((b & 0x007FFFFF)!=0))) { return -1; // one is NaN } return float32_cmp(a, b);}// flag float32_eq( float32 a, float32 b )static int float32_cmp(int a, int b){ // test for equal if (a == b) return 0; if ((( a | b )<<1) == 0) return 0; // positiv zero and negative zero are considered euqal // test for lt int aSign = a>>>31; int bSign = b>>>31; if ( aSign != bSign ) { // return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); return 1 if a < b if (aSign!=0 && ((( a | b )<<1) != 0)) { return -1; } else { return 1; } } // return ( a != b ) && ( aSign ^ ( a < b ) ); return 1 if a < b if ((a != b) && ((aSign ^ ((a<b) ? 1 : 0))!=0)) { return -1; } else { return 1; }//flag float32_lt( float32 a, float32 b )//{// flag aSign, bSign;//// 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//| the corresponding value `b', and 0 otherwise. The comparison is performed//| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.//*----------------------------------------------------------------------------*/////flag float32_eq( float32 a, float32 b )//{//// 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;// }// return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );////}/////*----------------------------------------------------------------------------//| Returns 1 if the single-precision floating-point value `a' is less than//| or equal to the corresponding value `b', and 0 otherwise. The comparison//| is performed according to the IEC/IEEE Standard for Binary Floating-Point//| Arithmetic.//*----------------------------------------------------------------------------*/////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 than//| the corresponding value `b', and 0 otherwise. The comparison is performed//| according 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//| the corresponding value `b', and 0 otherwise. The invalid exception is//| raised if either operand is a NaN. Otherwise, the comparison is performed//| according 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 or//| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not//| cause an exception. Otherwise, the comparison is performed according to the//| IEC/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 than//| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an//| exception. Otherwise, the comparison is performed according to the IEC/IEEE//| Standard 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 ) );////}//} // end class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -