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