|
|
1.1 root 1: /*---------------------------------------------------------------------------+
2: | poly_2xm1.c |
3: | |
4: | Function to compute 2^x-1 by a polynomial approximation. |
5: | |
6: | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
7: | Australia. E-mail [email protected] |
8: | |
9: | |
10: +---------------------------------------------------------------------------*/
11:
12: #include "fpu_system.h"
13: #include "exception.h"
14: #include "reg_constant.h"
15: #include "fpu_emu.h"
16:
17:
18:
19: #define HIPOWER 13
20: static unsigned short lterms[HIPOWER][4] =
21: {
22: { 0x79b5, 0xd1cf, 0x17f7, 0xb172 },
23: { 0x1b56, 0x058b, 0x7bff, 0x3d7f },
24: { 0x8bb0, 0x8250, 0x846b, 0x0e35 },
25: { 0xbc65, 0xf747, 0x556d, 0x0276 },
26: { 0x17cb, 0x9e39, 0x61ff, 0x0057 },
27: { 0xe018, 0x9776, 0x1848, 0x000a },
28: { 0x66f2, 0xff30, 0xffe5, 0x0000 },
29: { 0x682f, 0xffb6, 0x162b, 0x0000 },
30: { 0xb7ca, 0x2956, 0x01b5, 0x0000 },
31: { 0xcd3e, 0x4817, 0x001e, 0x0000 },
32: { 0xb7e2, 0xecbe, 0x0001, 0x0000 },
33: { 0x0ed5, 0x1a27, 0x0000, 0x0000 },
34: { 0x101d, 0x0222, 0x0000, 0x0000 },
35: };
36:
37:
38: /*--- poly_2xm1() -----------------------------------------------------------+
39: | |
40: +---------------------------------------------------------------------------*/
41: int poly_2xm1(FPU_REG *arg, FPU_REG *result)
42: {
43: short exponent;
44: long long Xll;
45: FPU_REG accum;
46:
47:
48: exponent = arg->exp - EXP_BIAS;
49:
50: if ( arg->tag == TW_Zero )
51: {
52: /* Return 0.0 */
53: reg_move(&CONST_Z, result);
54: return 0;
55: }
56:
57: if ( exponent >= 0 ) /* Can't hack a number >= 1.0 */
58: {
59: arith_invalid(result);
60: return 1;
61: }
62:
63: if ( arg->sign != SIGN_POS ) /* Can't hack a number < 0.0 */
64: {
65: arith_invalid(result);
66: return 1;
67: }
68:
69: if ( exponent < -64 )
70: {
71: reg_move(&CONST_LN2, result);
72: return 0;
73: }
74:
75: *(unsigned *)&Xll = arg->sigl;
76: *(((unsigned *)&Xll)+1) = arg->sigh;
77: if ( exponent < -1 )
78: {
79: /* shift the argument right by the required places */
80: if ( shrx(&Xll, -1-exponent) >= 0x80000000U )
81: Xll++; /* round up */
82: }
83:
84: *(short *)&(accum.sign) = 0; /* will be a valid positive nr with expon = 0 */
85: accum.exp = 0;
86:
87: /* Do the basic fixed point polynomial evaluation */
88: polynomial((unsigned *)&accum.sigl, (unsigned *)&Xll, lterms, HIPOWER-1);
89:
90: /* Convert to 64 bit signed-compatible */
91: accum.exp += EXP_BIAS - 1;
92:
93: reg_move(&accum, result);
94:
95: normalize(result);
96:
97: return 0;
98:
99: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.