~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/translator/cli/src/ll_math.cs

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
using System;
 
2
using System.Runtime.InteropServices;
 
3
using pypy.runtime;
 
4
 
 
5
namespace pypy.builtin
 
6
{
 
7
    public class ll_math
 
8
    {
 
9
 
 
10
        public static double ll_math_floor(double x)
 
11
        {
 
12
            return Math.Floor(x);
 
13
        }
 
14
 
 
15
        public static double ll_math_fmod(double x, double y)
 
16
        {
 
17
            return x % y;
 
18
        }
 
19
 
 
20
        public static Record_Float_Float ll_math_modf(double x)
 
21
        {
 
22
            Record_Float_Float result = new Record_Float_Float();
 
23
            result.item1 = (long)x; // truncate
 
24
            result.item0 = x - result.item1;
 
25
            return result;
 
26
        }
 
27
 
 
28
        // the following code is borrowed from 
 
29
        // http://web.telia.com/~u31115556/under_construction/Functions.Cephes.CFunctions.cs
 
30
        const double MAXNUM = double.MaxValue; // 1.79769313486232e308
 
31
        const int MEXP = 0x7ff;
 
32
 
 
33
        [StructLayout(LayoutKind.Explicit)] //, CLSCompliantAttribute(false)]
 
34
        struct DoubleUshorts 
 
35
        {
 
36
            [FieldOffset(0)] public double d;
 
37
            [FieldOffset(0)] public ushort u0;
 
38
            [FieldOffset(2)] public ushort u1;
 
39
            [FieldOffset(4)] public ushort u2;
 
40
            [FieldOffset(6)] public ushort u3;
 
41
        }
 
42
 
 
43
        public static unsafe Record_Float_Signed ll_math_frexp(double x)
 
44
        {
 
45
            Record_Float_Signed result = new Record_Float_Signed();
 
46
            if (x == 0.0) // Laj: Else pw2 = -1022
 
47
            {
 
48
                result.item0 = 0.0;
 
49
                result.item1 = 0;
 
50
                return result;
 
51
            }
 
52
 
 
53
            DoubleUshorts u;
 
54
            u.d = x;
 
55
 
 
56
            short *q = (short *)&u.u3;
 
57
 
 
58
            int i = (*q >> 4) & 0x7ff;
 
59
 
 
60
            i -= 0x3fe;
 
61
            result.item1 = i;
 
62
            unchecked
 
63
            {
 
64
                // Constant value '32783' cannot be converted to a 'short'
 
65
                *q &= (short)0x800f;
 
66
            }
 
67
            // Warning: Bitwise-or operator used on a sign-extended operand;
 
68
            // consider casting to a smaller unsigned type first
 
69
            *q |= 0x3fe0;
 
70
            result.item0 = u.d;
 
71
            return result;
 
72
        }
 
73
 
 
74
        static public unsafe double ll_math_ldexp(double x, int pw2)
 
75
        {
 
76
            DoubleUshorts u;
 
77
            u.d = x;
 
78
 
 
79
            short *q = (short *)&u.u3;
 
80
            double ud;
 
81
            int e;
 
82
            while ((e = (*q & 0x7ff0) >> 4) == 0)
 
83
            {
 
84
                if (u.d == 0.0)
 
85
                {
 
86
                    return 0.0;
 
87
                }
 
88
                // Input is denormal.
 
89
                if (pw2 > 0)
 
90
                {
 
91
                    u.d *= 2.0;
 
92
                    pw2 -= 1;
 
93
                }
 
94
                if (pw2 < 0)
 
95
                {
 
96
                    if (pw2 < -53)
 
97
                        return 0.0;
 
98
                    u.d /= 2.0;
 
99
                    pw2 += 1;
 
100
                }
 
101
                if (pw2 == 0)
 
102
                {
 
103
                    return u.d;
 
104
                }
 
105
            }
 
106
 
 
107
            e += pw2;
 
108
 
 
109
            // Handle overflow
 
110
            if (e >= MEXP)
 
111
                return 2.0*MAXNUM;
 
112
 
 
113
            if (e < 1)
 
114
            {
 
115
                return 0.0;
 
116
            }
 
117
            else
 
118
            {
 
119
                unchecked
 
120
                {
 
121
                    // Constant value '32783' cannot be converted to a 'short'
 
122
                    *q &= (short)0x800f;
 
123
                }
 
124
                // Cannot implicitly convert type 'int' to 'short'
 
125
                // Warning: Bitwise-or operator used on a sign-extended operand;
 
126
                // consider casting to a smaller unsigned type first
 
127
                *q |= (short)((e & 0x7ff) << 4);
 
128
                return u.d;
 
129
            }
 
130
        }
 
131
 
 
132
        static public double ll_math_atan2(double y, double x)
 
133
        {
 
134
            return Math.Atan2(y, x);
 
135
        }
 
136
 
 
137
        static public double ll_math_acos(double x)
 
138
        {
 
139
            return Math.Acos(x);
 
140
        }
 
141
 
 
142
        static public double ll_math_asin(double x)
 
143
        {
 
144
            return Math.Asin(x);
 
145
        }
 
146
 
 
147
        static public double ll_math_atan(double x)
 
148
        {
 
149
            return Math.Atan(x);
 
150
        }
 
151
 
 
152
        static public double ll_math_ceil(double x)
 
153
        {
 
154
            return Math.Ceiling(x);
 
155
        }
 
156
 
 
157
        static public double ll_math_cos(double x)
 
158
        {
 
159
            return Math.Cos(x);
 
160
        }
 
161
 
 
162
        static public double ll_math_cosh(double x)
 
163
        {
 
164
            return Math.Cosh(x);
 
165
        }
 
166
 
 
167
        static public double ll_math_exp(double x)
 
168
        {
 
169
            double res = Math.Exp(x);
 
170
            if (double.IsPositiveInfinity(res))
 
171
                Helpers.raise_OverflowError();
 
172
            return res;
 
173
        }
 
174
 
 
175
        static public double ll_math_fabs(double x)
 
176
        {
 
177
            return Math.Abs(x);
 
178
        }
 
179
 
 
180
        static public double ll_math_hypot(double x, double y)
 
181
        {
 
182
            return Math.Sqrt(x*x+y*y); // XXX: is it numerically correct?
 
183
        }
 
184
 
 
185
        static public double ll_math_log(double x)
 
186
        {
 
187
            return Math.Log(x);
 
188
        }
 
189
 
 
190
        static public double ll_math_log10(double x)
 
191
        {
 
192
            return Math.Log10(x);
 
193
        }
 
194
 
 
195
        static public double ll_math_pow(double x, double y)
 
196
        {
 
197
            return Math.Pow(x, y);
 
198
        }
 
199
 
 
200
        static public double ll_math_sin(double x)
 
201
        {
 
202
            return Math.Sin(x);
 
203
        }
 
204
 
 
205
        static public double ll_math_sinh(double x)
 
206
        {
 
207
            return Math.Sinh(x);
 
208
        }
 
209
 
 
210
        static public double ll_math_sqrt(double x)
 
211
        {
 
212
            double res = Math.Sqrt(x);
 
213
            if (double.IsNaN(res))
 
214
                Helpers.raise_ValueError();
 
215
            return res;
 
216
        }
 
217
 
 
218
        static public double ll_math_tan(double x)
 
219
        {
 
220
            return Math.Tan(x);
 
221
        }
 
222
 
 
223
        static public double ll_math_tanh(double x)
 
224
        {
 
225
            return Math.Tanh(x);
 
226
        }
 
227
    }
 
228
}