1 /* math.c - these are based on bob smith's csharp routines */
\r
5 #include <mono/metadata/sysmath.h>
\r
6 #include <mono/metadata/exception.h>
\r
9 # if G_BYTE_ORDER == G_BIG_ENDIAN
\r
10 # define __nan_bytes { 0x7f, 0xc0, 0, 0 }
\r
12 # if G_BYTE_ORDER == G_LITTLE_ENDIAN
\r
13 # define __nan_bytes { 0, 0, 0xc0, 0x7f }
\r
16 static union { unsigned char __c[4]; float __d; } __nan_union = { __nan_bytes };
\r
17 # define NAN (__nan_union.__d)
\r
21 #define __huge_val_t union { unsigned char __c[8]; double __d; }
\r
22 # if G_BYTE_ORDER == G_BIG_ENDIAN
\r
23 # define __HUGE_VAL_bytes { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
\r
25 # if G_BYTE_ORDER == G_LITTLE_ENDIAN
\r
26 # define __HUGE_VAL_bytes { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
\r
28 static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
\r
29 # define HUGE_VAL (__huge_val.__d)
\r
33 gdouble ves_icall_System_Math_Floor (gdouble x) {
\r
34 MONO_ARCH_SAVE_REGS;
\r
38 gdouble ves_icall_System_Math_Round (gdouble x) {
\r
39 double int_part, dec_part;
\r
40 MONO_ARCH_SAVE_REGS;
\r
41 int_part = floor(x);
\r
42 dec_part = x - int_part;
\r
43 if (((dec_part == 0.5) &&
\r
44 ((2.0 * ((int_part / 2.0) - floor(int_part / 2.0))) != 0.0)) ||
\r
51 gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits) {
\r
52 double p, int_part, dec_part;
\r
53 MONO_ARCH_SAVE_REGS;
\r
54 if (value == HUGE_VAL)
\r
56 if (value == -HUGE_VAL)
\r
59 return ves_icall_System_Math_Round(value);
\r
60 p = pow(10, digits);
\r
61 int_part = floor(value);
\r
62 dec_part = value - int_part;
\r
63 dec_part *= 1000000000000000;
\r
64 dec_part = floor(dec_part);
\r
65 dec_part /= (1000000000000000 / p);
\r
66 dec_part = ves_icall_System_Math_Round(dec_part);
\r
68 return int_part + dec_part;
\r
72 ves_icall_System_Math_Sin (gdouble x)
\r
74 MONO_ARCH_SAVE_REGS;
\r
80 ves_icall_System_Math_Cos (gdouble x)
\r
82 MONO_ARCH_SAVE_REGS;
\r
88 ves_icall_System_Math_Tan (gdouble x)
\r
90 MONO_ARCH_SAVE_REGS;
\r
96 ves_icall_System_Math_Sinh (gdouble x)
\r
98 MONO_ARCH_SAVE_REGS;
\r
104 ves_icall_System_Math_Cosh (gdouble x)
\r
106 MONO_ARCH_SAVE_REGS;
\r
112 ves_icall_System_Math_Tanh (gdouble x)
\r
114 MONO_ARCH_SAVE_REGS;
\r
120 ves_icall_System_Math_Acos (gdouble x)
\r
122 MONO_ARCH_SAVE_REGS;
\r
124 if (x < -1 || x > 1)
\r
131 ves_icall_System_Math_Asin (gdouble x)
\r
133 MONO_ARCH_SAVE_REGS;
\r
135 if (x < -1 || x > 1)
\r
142 ves_icall_System_Math_Atan (gdouble x)
\r
144 MONO_ARCH_SAVE_REGS;
\r
150 ves_icall_System_Math_Atan2 (gdouble y, gdouble x)
\r
153 MONO_ARCH_SAVE_REGS;
\r
155 if ((y == HUGE_VAL && x == HUGE_VAL) ||
\r
156 (y == HUGE_VAL && x == -HUGE_VAL) ||
\r
157 (y == -HUGE_VAL && x == HUGE_VAL) ||
\r
158 (y == -HUGE_VAL && x == -HUGE_VAL)) {
\r
161 result = atan2 (y, x);
\r
162 return (result == -0)? 0: result;
\r
166 ves_icall_System_Math_Exp (gdouble x)
\r
168 MONO_ARCH_SAVE_REGS;
\r
174 ves_icall_System_Math_Log (gdouble x)
\r
176 MONO_ARCH_SAVE_REGS;
\r
187 ves_icall_System_Math_Log10 (gdouble x)
\r
189 MONO_ARCH_SAVE_REGS;
\r
200 ves_icall_System_Math_Pow (gdouble x, gdouble y)
\r
203 MONO_ARCH_SAVE_REGS;
\r
205 if (isnan(x) || isnan(y)) {
\r
209 if ((x == 1 || x == -1) && (y == HUGE_VAL || y == -HUGE_VAL)) {
\r
213 /* This code is for return the same results as MS.NET for certain
\r
215 if (x < -9007199254740991.0) {
\r
216 if (y > 9007199254740991.0)
\r
218 if (y < -9007199254740991.0)
\r
222 result = pow (x, y);
\r
224 /* This code is for return the same results as MS.NET for certain
\r
226 if (isnan(result) &&
\r
228 ((y > 9007199254740991.0) || (y < -9007199254740991.0))) {
\r
232 return (result == -0)? 0: result;
\r
236 ves_icall_System_Math_Sqrt (gdouble x)
\r
238 MONO_ARCH_SAVE_REGS;
\r