Revision 8229c991 fpu/softfloat.c
b/fpu/softfloat.c | ||
---|---|---|
2056 | 2056 |
} |
2057 | 2057 |
|
2058 | 2058 |
/*---------------------------------------------------------------------------- |
2059 |
| Returns the binary exponential of the single-precision floating-point value |
|
2060 |
| `a'. The operation is performed according to the IEC/IEEE Standard for |
|
2061 |
| Binary Floating-Point Arithmetic. |
|
2062 |
| |
|
2063 |
| Uses the following identities: |
|
2064 |
| |
|
2065 |
| 1. ------------------------------------------------------------------------- |
|
2066 |
| x x*ln(2) |
|
2067 |
| 2 = e |
|
2068 |
| |
|
2069 |
| 2. ------------------------------------------------------------------------- |
|
2070 |
| 2 3 4 5 n |
|
2071 |
| x x x x x x x |
|
2072 |
| e = 1 + --- + --- + --- + --- + --- + ... + --- + ... |
|
2073 |
| 1! 2! 3! 4! 5! n! |
|
2074 |
*----------------------------------------------------------------------------*/ |
|
2075 |
|
|
2076 |
static const float64 float32_exp2_coefficients[15] = |
|
2077 |
{ |
|
2078 |
make_float64( 0x3ff0000000000000ll ), /* 1 */ |
|
2079 |
make_float64( 0x3fe0000000000000ll ), /* 2 */ |
|
2080 |
make_float64( 0x3fc5555555555555ll ), /* 3 */ |
|
2081 |
make_float64( 0x3fa5555555555555ll ), /* 4 */ |
|
2082 |
make_float64( 0x3f81111111111111ll ), /* 5 */ |
|
2083 |
make_float64( 0x3f56c16c16c16c17ll ), /* 6 */ |
|
2084 |
make_float64( 0x3f2a01a01a01a01all ), /* 7 */ |
|
2085 |
make_float64( 0x3efa01a01a01a01all ), /* 8 */ |
|
2086 |
make_float64( 0x3ec71de3a556c734ll ), /* 9 */ |
|
2087 |
make_float64( 0x3e927e4fb7789f5cll ), /* 10 */ |
|
2088 |
make_float64( 0x3e5ae64567f544e4ll ), /* 11 */ |
|
2089 |
make_float64( 0x3e21eed8eff8d898ll ), /* 12 */ |
|
2090 |
make_float64( 0x3de6124613a86d09ll ), /* 13 */ |
|
2091 |
make_float64( 0x3da93974a8c07c9dll ), /* 14 */ |
|
2092 |
make_float64( 0x3d6ae7f3e733b81fll ), /* 15 */ |
|
2093 |
}; |
|
2094 |
|
|
2095 |
float32 float32_exp2( float32 a STATUS_PARAM ) |
|
2096 |
{ |
|
2097 |
flag aSign; |
|
2098 |
int16 aExp; |
|
2099 |
bits32 aSig; |
|
2100 |
float64 r, x, xn; |
|
2101 |
int i; |
|
2102 |
|
|
2103 |
aSig = extractFloat32Frac( a ); |
|
2104 |
aExp = extractFloat32Exp( a ); |
|
2105 |
aSign = extractFloat32Sign( a ); |
|
2106 |
|
|
2107 |
if ( aExp == 0xFF) { |
|
2108 |
if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR ); |
|
2109 |
return (aSign) ? float32_zero : a; |
|
2110 |
} |
|
2111 |
if (aExp == 0) { |
|
2112 |
if (aSig == 0) return float32_one; |
|
2113 |
} |
|
2114 |
|
|
2115 |
float_raise( float_flag_inexact STATUS_VAR); |
|
2116 |
|
|
2117 |
/* ******************************* */ |
|
2118 |
/* using float64 for approximation */ |
|
2119 |
/* ******************************* */ |
|
2120 |
x = float32_to_float64(a STATUS_VAR); |
|
2121 |
x = float64_mul(x, float64_ln2 STATUS_VAR); |
|
2122 |
|
|
2123 |
xn = x; |
|
2124 |
r = float64_one; |
|
2125 |
for (i = 0 ; i < 15 ; i++) { |
|
2126 |
float64 f; |
|
2127 |
|
|
2128 |
f = float64_mul(xn, float32_exp2_coefficients[i] STATUS_VAR); |
|
2129 |
r = float64_add(r, f STATUS_VAR); |
|
2130 |
|
|
2131 |
xn = float64_mul(xn, x STATUS_VAR); |
|
2132 |
} |
|
2133 |
|
|
2134 |
return float64_to_float32(r, status); |
|
2135 |
} |
|
2136 |
|
|
2137 |
/*---------------------------------------------------------------------------- |
|
2059 | 2138 |
| Returns the binary log of the single-precision floating-point value `a'. |
2060 | 2139 |
| The operation is performed according to the IEC/IEEE Standard for Binary |
2061 | 2140 |
| Floating-Point Arithmetic. |
Also available in: Unified diff