/src/mupdf/thirdparty/mujs/jsmath.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "jsi.h" |
2 | | |
3 | | #if defined(_MSC_VER) && (_MSC_VER < 1700) /* VS2012 has stdint.h */ |
4 | | typedef unsigned int uint32_t; |
5 | | typedef unsigned __int64 uint64_t; |
6 | | #else |
7 | | #include <stdint.h> |
8 | | #endif |
9 | | |
10 | | #include <time.h> |
11 | | |
12 | | static double jsM_round(double x) |
13 | 0 | { |
14 | 0 | if (isnan(x)) return x; |
15 | 0 | if (isinf(x)) return x; |
16 | 0 | if (x == 0) return x; |
17 | 0 | if (x > 0 && x < 0.5) return 0; |
18 | 0 | if (x < 0 && x >= -0.5) return -0; |
19 | 0 | return floor(x + 0.5); |
20 | 0 | } |
21 | | |
22 | | static void Math_abs(js_State *J) |
23 | 0 | { |
24 | 0 | js_pushnumber(J, fabs(js_tonumber(J, 1))); |
25 | 0 | } |
26 | | |
27 | | static void Math_acos(js_State *J) |
28 | 0 | { |
29 | 0 | js_pushnumber(J, acos(js_tonumber(J, 1))); |
30 | 0 | } |
31 | | |
32 | | static void Math_asin(js_State *J) |
33 | 0 | { |
34 | 0 | js_pushnumber(J, asin(js_tonumber(J, 1))); |
35 | 0 | } |
36 | | |
37 | | static void Math_atan(js_State *J) |
38 | 0 | { |
39 | 0 | js_pushnumber(J, atan(js_tonumber(J, 1))); |
40 | 0 | } |
41 | | |
42 | | static void Math_atan2(js_State *J) |
43 | 0 | { |
44 | 0 | double y = js_tonumber(J, 1); |
45 | 0 | double x = js_tonumber(J, 2); |
46 | 0 | js_pushnumber(J, atan2(y, x)); |
47 | 0 | } |
48 | | |
49 | | static void Math_ceil(js_State *J) |
50 | 0 | { |
51 | 0 | js_pushnumber(J, ceil(js_tonumber(J, 1))); |
52 | 0 | } |
53 | | |
54 | | static void Math_cos(js_State *J) |
55 | 0 | { |
56 | 0 | js_pushnumber(J, cos(js_tonumber(J, 1))); |
57 | 0 | } |
58 | | |
59 | | static void Math_exp(js_State *J) |
60 | 0 | { |
61 | 0 | js_pushnumber(J, exp(js_tonumber(J, 1))); |
62 | 0 | } |
63 | | |
64 | | static void Math_floor(js_State *J) |
65 | 0 | { |
66 | 0 | js_pushnumber(J, floor(js_tonumber(J, 1))); |
67 | 0 | } |
68 | | |
69 | | static void Math_log(js_State *J) |
70 | 0 | { |
71 | 0 | js_pushnumber(J, log(js_tonumber(J, 1))); |
72 | 0 | } |
73 | | |
74 | | static void Math_pow(js_State *J) |
75 | 0 | { |
76 | 0 | double x = js_tonumber(J, 1); |
77 | 0 | double y = js_tonumber(J, 2); |
78 | 0 | if (!isfinite(y) && fabs(x) == 1) |
79 | 0 | js_pushnumber(J, NAN); |
80 | 0 | else |
81 | 0 | js_pushnumber(J, pow(x,y)); |
82 | 0 | } |
83 | | |
84 | | static void Math_random(js_State *J) |
85 | 0 | { |
86 | | /* Lehmer generator with a=48271 and m=2^31-1 */ |
87 | | /* Park & Miller (1988). Random Number Generators: Good ones are hard to find. */ |
88 | 0 | J->seed = (uint64_t) J->seed * 48271 % 0x7fffffff; |
89 | 0 | js_pushnumber(J, (double) J->seed / 0x7fffffff); |
90 | 0 | } |
91 | | |
92 | | static void Math_init_random(js_State *J) |
93 | 0 | { |
94 | | /* Pick initial seed by scrambling current time with Xorshift. */ |
95 | | /* Marsaglia (2003). Xorshift RNGs. */ |
96 | 0 | J->seed = time(0) + 123; |
97 | 0 | J->seed ^= J->seed << 13; |
98 | 0 | J->seed ^= J->seed >> 17; |
99 | 0 | J->seed ^= J->seed << 5; |
100 | 0 | J->seed %= 0x7fffffff; |
101 | 0 | } |
102 | | |
103 | | static void Math_round(js_State *J) |
104 | 0 | { |
105 | 0 | double x = js_tonumber(J, 1); |
106 | 0 | js_pushnumber(J, jsM_round(x)); |
107 | 0 | } |
108 | | |
109 | | static void Math_sin(js_State *J) |
110 | 0 | { |
111 | 0 | js_pushnumber(J, sin(js_tonumber(J, 1))); |
112 | 0 | } |
113 | | |
114 | | static void Math_sqrt(js_State *J) |
115 | 0 | { |
116 | 0 | js_pushnumber(J, sqrt(js_tonumber(J, 1))); |
117 | 0 | } |
118 | | |
119 | | static void Math_tan(js_State *J) |
120 | 0 | { |
121 | 0 | js_pushnumber(J, tan(js_tonumber(J, 1))); |
122 | 0 | } |
123 | | |
124 | | static void Math_max(js_State *J) |
125 | 0 | { |
126 | 0 | int i, n = js_gettop(J); |
127 | 0 | double x = -INFINITY; |
128 | 0 | for (i = 1; i < n; ++i) { |
129 | 0 | double y = js_tonumber(J, i); |
130 | 0 | if (isnan(y)) { |
131 | 0 | x = y; |
132 | 0 | break; |
133 | 0 | } |
134 | 0 | if (signbit(x) == signbit(y)) |
135 | 0 | x = x > y ? x : y; |
136 | 0 | else if (signbit(x)) |
137 | 0 | x = y; |
138 | 0 | } |
139 | 0 | js_pushnumber(J, x); |
140 | 0 | } |
141 | | |
142 | | static void Math_min(js_State *J) |
143 | 0 | { |
144 | 0 | int i, n = js_gettop(J); |
145 | 0 | double x = INFINITY; |
146 | 0 | for (i = 1; i < n; ++i) { |
147 | 0 | double y = js_tonumber(J, i); |
148 | 0 | if (isnan(y)) { |
149 | 0 | x = y; |
150 | 0 | break; |
151 | 0 | } |
152 | 0 | if (signbit(x) == signbit(y)) |
153 | 0 | x = x < y ? x : y; |
154 | 0 | else if (signbit(y)) |
155 | 0 | x = y; |
156 | 0 | } |
157 | 0 | js_pushnumber(J, x); |
158 | 0 | } |
159 | | |
160 | | void jsB_initmath(js_State *J) |
161 | 0 | { |
162 | 0 | Math_init_random(J); |
163 | 0 | js_pushobject(J, jsV_newobject(J, JS_CMATH, J->Object_prototype)); |
164 | 0 | { |
165 | 0 | jsB_propn(J, "E", 2.7182818284590452354); |
166 | 0 | jsB_propn(J, "LN10", 2.302585092994046); |
167 | 0 | jsB_propn(J, "LN2", 0.6931471805599453); |
168 | 0 | jsB_propn(J, "LOG2E", 1.4426950408889634); |
169 | 0 | jsB_propn(J, "LOG10E", 0.4342944819032518); |
170 | 0 | jsB_propn(J, "PI", 3.1415926535897932); |
171 | 0 | jsB_propn(J, "SQRT1_2", 0.7071067811865476); |
172 | 0 | jsB_propn(J, "SQRT2", 1.4142135623730951); |
173 | |
|
174 | 0 | jsB_propf(J, "Math.abs", Math_abs, 1); |
175 | 0 | jsB_propf(J, "Math.acos", Math_acos, 1); |
176 | 0 | jsB_propf(J, "Math.asin", Math_asin, 1); |
177 | 0 | jsB_propf(J, "Math.atan", Math_atan, 1); |
178 | 0 | jsB_propf(J, "Math.atan2", Math_atan2, 2); |
179 | 0 | jsB_propf(J, "Math.ceil", Math_ceil, 1); |
180 | 0 | jsB_propf(J, "Math.cos", Math_cos, 1); |
181 | 0 | jsB_propf(J, "Math.exp", Math_exp, 1); |
182 | 0 | jsB_propf(J, "Math.floor", Math_floor, 1); |
183 | 0 | jsB_propf(J, "Math.log", Math_log, 1); |
184 | 0 | jsB_propf(J, "Math.max", Math_max, 0); /* 2 */ |
185 | 0 | jsB_propf(J, "Math.min", Math_min, 0); /* 2 */ |
186 | 0 | jsB_propf(J, "Math.pow", Math_pow, 2); |
187 | 0 | jsB_propf(J, "Math.random", Math_random, 0); |
188 | 0 | jsB_propf(J, "Math.round", Math_round, 1); |
189 | 0 | jsB_propf(J, "Math.sin", Math_sin, 1); |
190 | 0 | jsB_propf(J, "Math.sqrt", Math_sqrt, 1); |
191 | 0 | jsB_propf(J, "Math.tan", Math_tan, 1); |
192 | 0 | } |
193 | 0 | js_defglobal(J, "Math", JS_DONTENUM); |
194 | 0 | } |