📄 softfloat.java
字号:
}; int8 shiftCount; shiftCount = 0; if ( a < 0x10000 ) { shiftCount += 16; a <<= 16; } if ( a < 0x1000000 ) { shiftCount += 8; a <<= 8; } shiftCount += countLeadingZerosHigh[ a>>24 ]; return shiftCount;*/ int cnt; for (cnt=0; cnt<32; ++cnt) { if (a < 0) { // MSB set break; } a <<= 1; } return cnt;}///*----------------------------------------------------------------------------//| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is//| equal to the 64-bit value formed by concatenating `b0' and `b1'. Otherwise,//| returns 0.//*----------------------------------------------------------------------------*/////INLINE flag eq64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )//{//// return ( a0 == b0 ) && ( a1 == b1 );////}/////*----------------------------------------------------------------------------//| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less//| than or equal to the 64-bit value formed by concatenating `b0' and `b1'.//| Otherwise, returns 0.//*----------------------------------------------------------------------------*/////INLINE flag le64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )//{//// return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );////}/////*----------------------------------------------------------------------------//| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less//| than the 64-bit value formed by concatenating `b0' and `b1'. Otherwise,//| returns 0.//*----------------------------------------------------------------------------*/////INLINE flag lt64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )//{//// return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );////}/////*----------------------------------------------------------------------------//| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is not//| equal to the 64-bit value formed by concatenating `b0' and `b1'. Otherwise,//| returns 0.//*----------------------------------------------------------------------------*/////INLINE flag ne64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )//{//// return ( a0 != b0 ) || ( a1 != b1 );////}// end #include "softfloat-macros"/*----------------------------------------------------------------------------| Functions and definitions to determine: (1) whether tininess for underflow| is detected before or after rounding by default, (2) what (if anything)| happens when exceptions are raised, (3) how signaling NaNs are distinguished| from quiet NaNs, (4) the default generated quiet NaNs, and (4) how NaNs| are propagated from function inputs to output. These details are target-| specific.*----------------------------------------------------------------------------*/// #include "softfloat-specialize"//**************** thats the include/////*----------------------------------------------------------------------------//| Underflow tininess-detection mode, statically initialized to default value.//| (The declaration in `softfloat.h' must match the `int8' type here.)//*----------------------------------------------------------------------------*///int8 float_detect_tininess = float_tininess_before_rounding;/////*----------------------------------------------------------------------------//| Raises the exceptions specified by `flags'. Floating-point traps can be//| defined here if desired. It is currently not possible for such a trap//| to substitute a result value. If traps are not implemented, this routine//| should be simply `float_exception_flags |= flags;'.//*----------------------------------------------------------------------------*/////void float_raise( int8 flags )//{//// float_exception_flags |= flags;////}/////*----------------------------------------------------------------------------//| Internal canonical NaN format.//*----------------------------------------------------------------------------*///typedef struct {// flag sign;// bits32 high, low;//} commonNaNT;/////*----------------------------------------------------------------------------//| The pattern for a default generated single-precision NaN.//*----------------------------------------------------------------------------*///enum {// float32_default_nan = 0x7FFFFFFF//};///*----------------------------------------------------------------------------| Returns 1 if the single-precision floating-point value `a' is a NaN;| otherwise returns 0.*----------------------------------------------------------------------------*//* I don't need itstatic boolean float32_is_nan(int a){ return ( 0xFF000000 < (a<<1) );}*//////*----------------------------------------------------------------------------//| Returns 1 if the single-precision floating-point value `a' is a signaling//| NaN; otherwise returns 0.//*----------------------------------------------------------------------------*/////flag float32_is_signaling_nan( float32 a )//{//// return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );////}/////*----------------------------------------------------------------------------//| Returns the result of converting the single-precision floating-point NaN//| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid//| exception is raised.//*----------------------------------------------------------------------------*/////static commonNaNT float32ToCommonNaN( float32 a )//{// commonNaNT z;//// if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );// z.sign = a>>31;// z.low = 0;// z.high = a<<9;// return z;////}/////*----------------------------------------------------------------------------//| Returns the result of converting the canonical NaN `a' to the single-//| precision floating-point format.//*----------------------------------------------------------------------------*/////static float32 commonNaNToFloat32( commonNaNT a )//{//// return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>9 );////}///*----------------------------------------------------------------------------| Takes two single-precision floating-point values `a' and `b', one of which| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a| signaling NaN, the invalid exception is raised.*----------------------------------------------------------------------------*/// signaling removed// could be simpler.../*static int propagateFloat32NaN( int a, int b ){ boolean bIsNaN;return 0x7fc00000; // aIsNaN = float32_is_nan( a ); bIsNaN = float32_is_nan( b ); a |= 0x00400000; b |= 0x00400000; return bIsNaN ? b : a;}*///**************** end include/*----------------------------------------------------------------------------| Returns the fraction bits of the single-precision floating-point value `a'.*----------------------------------------------------------------------------*//*static int extractFloat32Frac(int a){ return a & 0x007FFFFF;}*//*----------------------------------------------------------------------------| Returns the exponent bits of the single-precision floating-point value `a'.*----------------------------------------------------------------------------*//*static int extractFloat32Exp(int a){ return ( a>>>23 ) & 0xFF;}*//*----------------------------------------------------------------------------| Returns the sign bit of the single-precision floating-point value `a'.*----------------------------------------------------------------------------*//*static int extractFloat32Sign(int a){ return a>>>31;}*//////*----------------------------------------------------------------------------//| Normalizes the subnormal single-precision floating-point value represented//| by the denormalized significand `aSig'. The normalized exponent and//| significand are stored at the locations pointed to by `zExpPtr' and//| `zSigPtr', respectively.//*----------------------------------------------------------------------------*/////static void// normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )//{// int8 shiftCount;//// shiftCount = countLeadingZeros32( aSig ) - 8;// *zSigPtr = aSig<<shiftCount;// *zExpPtr = 1 - shiftCount;////}///*----------------------------------------------------------------------------| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a| single-precision floating-point value, returning the result. After being| shifted into the proper positions, the three fields are simply added| together to form the result. This means that any integer portion of `zSig'| will be added into the exponent. Since a properly normalized significand| will have an integer portion equal to 1, the `zExp' input should be 1 less| than the desired result exponent whenever `zSig' is a complete, normalized| significand.*----------------------------------------------------------------------------*///INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )/*static int packFloat32( int zSign, int zExp, int zSig ){ return ( ( zSign )<<31 ) + ( ( zExp )<<23 ) + zSig;}*//*----------------------------------------------------------------------------| Takes an abstract floating-point value having sign `zSign', exponent `zExp',| and significand `zSig', and returns the proper single-precision floating-| point value corresponding to the abstract input. Ordinarily, the abstract| value is simply rounded and packed into the single-precision format, with| the inexact exception raised if the abstract input cannot be represented| exactly. However, if the abstract value is too large, the overflow and| inexact exceptions are raised and an infinity or maximal finite value is| returned. If the abstract value is too small, the input value is rounded to| a subnormal number, and the underflow and inexact exceptions are raised if| the abstract input cannot be represented exactly as a subnormal single-| precision floating-point number.| The input significand `zSig' has its binary point between bits 30| and 29, which is 7 bits to the left of the usual location. This shifted| significand must be normalized or smaller. If `zSig' is not normalized,| `zExp' must be 0; in that case, the result returned is a subnormal number,| and it must not require rounding. In the usual case that `zSig' is| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.| The handling of underflow and overflow follows the IEC/IEEE Standard for| Binary Floating-Point Arithmetic.*----------------------------------------------------------------------------*///static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )static int roundAndPackFloat32( int zSign, int zExp, int zSig ){ // int8 roundingMode; // flag roundNearestEven; // int8 roundIncrement, roundBits; // flag isTiny; int roundIncrement, roundBits; roundIncrement = 0x40; // round to nearst in Java roundBits = zSig & 0x7F; // if ( 0xFD <= (bits16) zExp ) { if ( 0xFD <= (zExp & 0xffff) ) { if ( ( 0xFD < zExp ) || ( ( zExp == 0xFD ) // && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) && ( ( zSig + roundIncrement ) < 0 ) ) ) {// float_raise( float_flag_overflow | float_flag_inexact ); // return packFloat32( zSign, 0xFF, 0 ) - ((roundIncrement == 0) ? 1 : 0); return (((zSign)<<31) + ((0xff)<<23)) - ((roundIncrement == 0) ? 1 : 0); } if ( zExp < 0 ) {/* isTiny = ( float_detect_tininess == float_tininess_before_rounding ) || ( zExp < -1 ) || ( zSig + roundIncrement < 0x80000000 );*/ zSig = shift32RightJamming( zSig, -zExp); zExp = 0; roundBits = zSig & 0x7F;// if ( isTiny && roundBits ) float_raise( float_flag_underflow ); } }// if ( roundBits ) float_exception_flags |= float_flag_inexact; zSig = ( zSig + roundIncrement )>>>7; zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) ? 1 : 0 ); if ( zSig == 0 ) zExp = 0; // return packFloat32( zSign, zExp, zSig ); return (((zSign)<<31) + ((zExp)<<23) + zSig);}/*----------------------------------------------------------------------------| Takes an abstract floating-point value having sign `zSign', exponent `zExp',| and significand `zSig', and returns the proper single-precision floating-| point value corresponding to the abstract input. This routine is just like| `roundAndPackFloat32' except that `zSig' does not have to be normalized.| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''| floating-point exponent.*----------------------------------------------------------------------------*/// static float32 normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )static int normalizeRoundAndPackFloat32( int zSign, int zExp, int zSig ){ int shiftCount; // shiftCount = countLeadingZeros32( zSig ) - 1; int a = zSig; for (shiftCount=0; shiftCount<32; ++shiftCount) { if (a < 0) { // MSB set break; } a <<= 1; } shiftCount -= 1; return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );}/*----------------------------------------------------------------------------| Returns the result of converting the 32-bit two's complement integer `a' to| the single-precision floating-point format. The conversion is performed| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.*----------------------------------------------------------------------------*/// float32 int32_to_float32( int32 a )public static int int32_to_float32( int a ){ // flag zSign; int zSign; if ( a == 0 ) return 0; // if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); if (a == 0x80000000) return (( 1 )<<31) + ( ( 0x9E )<<23 ); // zSign = (a < 0); zSign = a>>>31; return normalizeRoundAndPackFloat32( zSign, 0x9C, (zSign!=0) ? -a : a );}/*----------------------------------------------------------------------------| Returns the result of converting the single-precision floating-point value| `a' to the 32-bit two's complement integer format. The conversion is| performed according to the IEC/IEEE Standard for Binary Floating-Point| Arithmetic---which means in particular that the conversion is rounded| according to the current rounding mode. If `a' is a NaN, the largest| positive integer is returned. Otherwise, if the conversion overflows, the| largest integer with the same sign as `a' is returned.*----------------------------------------------------------------------------*//* no rounding used in Java.// int32 float32_to_int32( float32 a )public static int float32_to_int32( int a ){ // flag aSign; // int16 aExp, shiftCount; // bits32 aSig, aSigExtra; // int32 z; // int8 roundingMode; int aSign; int aExp, shiftCount; int aSig, aSigExtra; int z; int roundingMode; // aSig = extractFloat32Frac( a ); // aExp = extractFloat32Exp( a ); // aSign = extractFloat32Sign( a ); aSig = a & 0x007FFFFF; aExp = ( a>>>23 ) & 0xFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -