Coverage Report

Created: 2025-11-24 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsMath.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2025  Moddable Tech, Inc.
3
 *
4
 *   This file is part of the Moddable SDK Runtime.
5
 * 
6
 *   The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
 *   it under the terms of the GNU Lesser General Public License as published by
8
 *   the Free Software Foundation, either version 3 of the License, or
9
 *   (at your option) any later version.
10
 * 
11
 *   The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU Lesser General Public License for more details.
15
 * 
16
 *   You should have received a copy of the GNU Lesser General Public License
17
 *   along with the Moddable SDK Runtime.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * This file incorporates work covered by the following copyright and  
20
 * permission notice:  
21
 *
22
 *       Copyright (C) 2010-2016 Marvell International Ltd.
23
 *       Copyright (C) 2002-2010 Kinoma, Inc.
24
 *
25
 *       Licensed under the Apache License, Version 2.0 (the "License");
26
 *       you may not use this file except in compliance with the License.
27
 *       You may obtain a copy of the License at
28
 *
29
 *        http://www.apache.org/licenses/LICENSE-2.0
30
 *
31
 *       Unless required by applicable law or agreed to in writing, software
32
 *       distributed under the License is distributed on an "AS IS" BASIS,
33
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
 *       See the License for the specific language governing permissions and
35
 *       limitations under the License.
36
 */
37
38
#include "xsAll.h"
39
40
void fxBuildMath(txMachine* the)
41
27.4k
{
42
27.4k
  txSlot* slot;
43
27.4k
  mxPush(mxObjectPrototype);
44
27.4k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
45
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_abs), 1, mxID(_abs), XS_DONT_ENUM_FLAG);
46
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_acos), 1, mxID(_acos), XS_DONT_ENUM_FLAG);
47
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_acosh), 1, mxID(_acosh), XS_DONT_ENUM_FLAG);
48
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_asin), 1, mxID(_asin), XS_DONT_ENUM_FLAG);
49
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_asinh), 1, mxID(_asinh), XS_DONT_ENUM_FLAG);
50
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_atan), 1, mxID(_atan), XS_DONT_ENUM_FLAG);
51
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_atanh), 1, mxID(_atanh), XS_DONT_ENUM_FLAG);
52
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_atan2), 2, mxID(_atan2), XS_DONT_ENUM_FLAG);
53
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_cbrt), 1, mxID(_cbrt), XS_DONT_ENUM_FLAG);
54
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_ceil), 1, mxID(_ceil), XS_DONT_ENUM_FLAG);
55
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_clz32), 1, mxID(_clz32), XS_DONT_ENUM_FLAG);
56
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_cos), 1, mxID(_cos), XS_DONT_ENUM_FLAG);
57
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_cosh), 1, mxID(_cosh), XS_DONT_ENUM_FLAG);
58
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_exp), 1, mxID(_exp), XS_DONT_ENUM_FLAG);
59
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_expm1), 1, mxID(_expm1), XS_DONT_ENUM_FLAG);
60
27.4k
#if mxFloat16
61
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_f16round), 1, mxID(_f16round), XS_DONT_ENUM_FLAG);
62
27.4k
#endif
63
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_floor), 1, mxID(_floor), XS_DONT_ENUM_FLAG);
64
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_fround), 1, mxID(_fround), XS_DONT_ENUM_FLAG);
65
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_hypot), 2, mxID(_hypot_), XS_DONT_ENUM_FLAG);
66
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_idiv), 2, mxID(_idiv), XS_DONT_ENUM_FLAG);
67
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_idivmod), 2, mxID(_idivmod), XS_DONT_ENUM_FLAG);
68
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_imod), 2, mxID(_imod), XS_DONT_ENUM_FLAG);
69
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_imul), 2, mxID(_imul), XS_DONT_ENUM_FLAG);
70
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_imuldiv), 2, mxID(_imuldiv), XS_DONT_ENUM_FLAG);
71
27.4k
#if mxECMAScript2023
72
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_irandom), 0, mxID(_irandom), XS_DONT_ENUM_FLAG);
73
27.4k
#endif
74
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_irem), 2, mxID(_irem), XS_DONT_ENUM_FLAG);
75
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_log), 1, mxID(_log), XS_DONT_ENUM_FLAG);
76
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_log1p), 1, mxID(_log1p), XS_DONT_ENUM_FLAG);
77
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_log10), 1, mxID(_log10), XS_DONT_ENUM_FLAG);
78
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_log2), 1, mxID(_log2), XS_DONT_ENUM_FLAG);
79
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_max), 2, mxID(_max), XS_DONT_ENUM_FLAG);
80
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_min), 2, mxID(_min), XS_DONT_ENUM_FLAG);
81
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_mod), 2, mxID(_mod), XS_DONT_ENUM_FLAG);
82
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_pow), 2, mxID(_pow), XS_DONT_ENUM_FLAG);
83
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_random), 0, mxID(_random), XS_DONT_ENUM_FLAG);
84
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_round), 1, mxID(_round), XS_DONT_ENUM_FLAG);
85
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_sign), 1, mxID(_sign), XS_DONT_ENUM_FLAG);
86
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_sin), 1, mxID(_sin), XS_DONT_ENUM_FLAG);
87
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_sinh), 1, mxID(_sinh), XS_DONT_ENUM_FLAG);
88
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_sqrt), 1, mxID(_sqrt), XS_DONT_ENUM_FLAG);
89
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_tan), 1, mxID(_tan), XS_DONT_ENUM_FLAG);
90
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_tanh), 1, mxID(_tanh), XS_DONT_ENUM_FLAG);
91
27.4k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Math_trunc), 1, mxID(_trunc), XS_DONT_ENUM_FLAG);
92
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_E, mxID(_E), XS_GET_ONLY);
93
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_LN10, mxID(_LN10), XS_GET_ONLY);
94
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_LN2, mxID(_LN2), XS_GET_ONLY);
95
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_LOG10E, mxID(_LOG10E), XS_GET_ONLY);
96
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_LOG2E, mxID(_LOG2E), XS_GET_ONLY);
97
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_PI, mxID(_PI), XS_GET_ONLY);
98
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_SQRT1_2, mxID(_SQRT1_2), XS_GET_ONLY);
99
27.4k
  slot = fxNextNumberProperty(the, slot, C_M_SQRT2, mxID(_SQRT2), XS_GET_ONLY);
100
27.4k
  slot = fxNextStringXProperty(the, slot, "Math", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
101
27.4k
  mxPull(mxMathObject);
102
//@@  c_srand((unsigned)c_time(0));
103
27.4k
}
104
105
#define mxNanResultIfNoArg \
106
2.08M
  if (mxArgc < 1) {  \
107
11.7k
    mxResult->kind = XS_NUMBER_KIND; \
108
11.7k
    mxResult->value.number = C_NAN; \
109
11.7k
    return; \
110
11.7k
  }
111
112
#define mxNanResultIfNoArg2 \
113
962k
  if (mxArgc < 2) {  \
114
48.1k
    mxResult->kind = XS_NUMBER_KIND; \
115
48.1k
    mxResult->value.number = C_NAN; \
116
48.1k
    return; \
117
48.1k
  }
118
119
void fx_Math_abs(txMachine* the)
120
20
{
121
20
  mxNanResultIfNoArg;
122
20
  fxToNumber(the, mxArgv(0));
123
20
  mxResult->kind = XS_NUMBER_KIND;
124
20
  mxResult->value.number = c_fabs(mxArgv(0)->value.number);
125
20
}
126
127
void fx_Math_acos(txMachine* the)
128
18.7k
{
129
18.7k
  mxNanResultIfNoArg;
130
16.6k
  fxToNumber(the, mxArgv(0));
131
16.6k
  mxResult->kind = XS_NUMBER_KIND;
132
16.6k
  mxResult->value.number = c_acos(mxArgv(0)->value.number);
133
16.6k
}
134
135
void fx_Math_acosh(txMachine* the)
136
183k
{
137
183k
  mxNanResultIfNoArg;
138
182k
  fxToNumber(the, mxArgv(0));
139
182k
  mxResult->kind = XS_NUMBER_KIND;
140
182k
  mxResult->value.number = c_acosh(mxArgv(0)->value.number);
141
182k
}
142
143
void fx_Math_asin(txMachine* the)
144
9.67k
{
145
9.67k
  mxNanResultIfNoArg;
146
8.29k
  fxToNumber(the, mxArgv(0));
147
8.29k
  mxResult->kind = XS_NUMBER_KIND;
148
8.29k
  mxResult->value.number = c_asin(mxArgv(0)->value.number);
149
8.29k
}
150
151
void fx_Math_asinh(txMachine* the)
152
55.8k
{
153
55.8k
  mxNanResultIfNoArg;
154
55.8k
  fxToNumber(the, mxArgv(0));
155
55.8k
  mxResult->kind = XS_NUMBER_KIND;
156
55.8k
  mxResult->value.number = c_asinh(mxArgv(0)->value.number);
157
55.8k
}
158
159
void fx_Math_atan(txMachine* the)
160
8.20k
{
161
8.20k
  mxNanResultIfNoArg;
162
6.08k
  fxToNumber(the, mxArgv(0));
163
6.08k
  mxResult->kind = XS_NUMBER_KIND;
164
6.08k
  mxResult->value.number = c_atan(mxArgv(0)->value.number);
165
6.08k
}
166
167
void fx_Math_atanh(txMachine* the)
168
739k
{
169
739k
  mxNanResultIfNoArg;
170
739k
  fxToNumber(the, mxArgv(0));
171
739k
  mxResult->kind = XS_NUMBER_KIND;
172
739k
  mxResult->value.number = c_atanh(mxArgv(0)->value.number);
173
739k
}
174
175
void fx_Math_atan2(txMachine* the)
176
756k
{
177
756k
  mxNanResultIfNoArg2;
178
756k
  fxToNumber(the, mxArgv(0));
179
756k
  fxToNumber(the, mxArgv(1));
180
756k
  mxResult->kind = XS_NUMBER_KIND;
181
756k
  mxResult->value.number = c_atan2(mxArgv(0)->value.number, mxArgv(1)->value.number);
182
756k
}
183
184
void fx_Math_cbrt(txMachine* the)
185
20
{
186
20
  mxNanResultIfNoArg;
187
20
  fxToNumber(the, mxArgv(0));
188
20
  mxResult->kind = XS_NUMBER_KIND;
189
20
  mxResult->value.number = c_cbrt(mxArgv(0)->value.number);
190
20
}
191
192
void fx_Math_ceil(txMachine* the)
193
69.4k
{
194
69.4k
  mxNanResultIfNoArg;
195
69.4k
  if (XS_INTEGER_KIND == mxArgv(0)->kind) {
196
9
    mxResult->kind = XS_INTEGER_KIND;
197
9
    mxResult->value.integer = mxArgv(0)->value.integer;
198
9
    return;
199
9
  }
200
69.4k
  fxToNumber(the, mxArgv(0));
201
69.4k
  mxResult->kind = XS_NUMBER_KIND;
202
69.4k
  mxResult->value.number = c_ceil(mxArgv(0)->value.number);
203
69.4k
  fx_Math_toInteger(the);
204
69.4k
}
205
206
void fx_Math_clz32(txMachine* the)
207
55
{
208
55
  txUnsigned x = (mxArgc > 0) ? fxToUnsigned(the, mxArgv(0)) : 0;
209
55
  txInteger r;
210
55
  if (x)
211
#if mxWindows
212
  {
213
    _BitScanReverse(&r, x);
214
    r = 31 - r;
215
  }
216
#else
217
43
    r = __builtin_clz(x);
218
12
#endif  
219
12
  else
220
12
    r = 32;
221
55
  mxResult->kind = XS_INTEGER_KIND;
222
55
  mxResult->value.integer = r;
223
55
}
224
225
void fx_Math_cos(txMachine* the)
226
324k
{
227
324k
  mxNanResultIfNoArg;
228
324k
  fxToNumber(the, mxArgv(0));
229
324k
  mxResult->kind = XS_NUMBER_KIND;
230
324k
  mxResult->value.number = c_cos(mxArgv(0)->value.number);
231
324k
}
232
233
void fx_Math_cosh(txMachine* the)
234
25.7k
{
235
25.7k
  mxNanResultIfNoArg;
236
25.0k
  fxToNumber(the, mxArgv(0));
237
25.0k
  mxResult->kind = XS_NUMBER_KIND;
238
25.0k
  mxResult->value.number = c_cosh(mxArgv(0)->value.number);
239
25.0k
}
240
241
void fx_Math_exp(txMachine* the)
242
119k
{
243
119k
  mxNanResultIfNoArg;
244
118k
  fxToNumber(the, mxArgv(0));
245
118k
  mxResult->kind = XS_NUMBER_KIND;
246
118k
  mxResult->value.number = c_exp(mxArgv(0)->value.number);
247
118k
}
248
249
void fx_Math_expm1(txMachine* the)
250
26
{
251
26
  mxNanResultIfNoArg;
252
26
  fxToNumber(the, mxArgv(0));
253
26
  mxResult->kind = XS_NUMBER_KIND;
254
26
  mxResult->value.number = c_expm1(mxArgv(0)->value.number);
255
26
}
256
257
void fx_Math_floor(txMachine* the)
258
149k
{
259
149k
  mxNanResultIfNoArg;
260
149k
  if (XS_INTEGER_KIND == mxArgv(0)->kind) {
261
66.8k
    mxResult->kind = XS_INTEGER_KIND;
262
66.8k
    mxResult->value.integer = mxArgv(0)->value.integer;
263
66.8k
    return;
264
66.8k
  }
265
82.8k
  fxToNumber(the, mxArgv(0));
266
82.8k
  mxResult->kind = XS_NUMBER_KIND;
267
82.8k
  mxResult->value.number = c_floor(mxArgv(0)->value.number);
268
82.8k
  fx_Math_toInteger(the);
269
82.8k
}
270
271
void fx_Math_fround(txMachine* the)
272
53
{
273
53
  float arg;
274
53
  mxNanResultIfNoArg;
275
52
  if (XS_INTEGER_KIND == mxArgv(0)->kind) {
276
6
    mxResult->kind = XS_INTEGER_KIND;
277
6
    mxResult->value.integer = mxArgv(0)->value.integer;
278
6
    return;
279
6
  }
280
46
  arg = (float)fxToNumber(the, mxArgv(0));
281
46
  mxResult->kind = XS_NUMBER_KIND;
282
46
  mxResult->value.number = arg;
283
46
}
284
285
void fx_Math_hypot(txMachine* the)
286
32
{
287
32
  if (mxArgc == 2) {
288
18
    fxToNumber(the, mxArgv(0));
289
18
    fxToNumber(the, mxArgv(1));
290
18
    mxResult->kind = XS_NUMBER_KIND;
291
18
    mxResult->value.number = c_hypot(mxArgv(0)->value.number, mxArgv(1)->value.number);
292
18
  }
293
14
  else {
294
14
    txInteger c = mxArgc, i;
295
14
    txNumber result = 0;
296
34
    for (i = 0; i < c; i++) {
297
20
      txNumber argument = fxToNumber(the, mxArgv(i));
298
20
      result += argument * argument;
299
20
    }
300
14
    mxResult->kind = XS_NUMBER_KIND;
301
14
    mxResult->value.number = c_sqrt(result);
302
14
  }
303
32
}
304
305
void fx_Math_idiv(txMachine* the)
306
26.3k
{
307
26.3k
  txInteger x = (mxArgc > 0) ? fxToInteger(the, mxArgv(0)) : 0;
308
26.3k
  txInteger y = (mxArgc > 1) ? fxToInteger(the, mxArgv(1)) : 0;
309
26.3k
  if (y == 0) {
310
25.7k
    mxResult->kind = XS_NUMBER_KIND;
311
25.7k
    mxResult->value.number = C_NAN;
312
25.7k
  }
313
556
  else {
314
556
    mxResult->kind = XS_INTEGER_KIND;
315
556
#if mxIntegerDivideOverflowException
316
556
    if ((x == (txInteger)0x80000000) && (y == -1))
317
4
      mxResult->value.integer = x;
318
552
    else
319
552
#endif
320
552
      mxResult->value.integer = x / y;
321
556
  }
322
26.3k
}
323
324
void fx_Math_idivmod(txMachine* the)
325
0
{
326
0
  mxTypeError("not available");
327
0
}
328
329
void fx_Math_imod(txMachine* the)
330
0
{
331
0
  txInteger x = (mxArgc > 0) ? fxToInteger(the, mxArgv(0)) : 0;
332
0
  txInteger y = (mxArgc > 1) ? fxToInteger(the, mxArgv(1)) : 0;
333
0
  if (y == 0) {
334
0
    mxResult->kind = XS_NUMBER_KIND;
335
0
    mxResult->value.number = C_NAN;
336
0
  }
337
0
  else {
338
0
    mxResult->kind = XS_INTEGER_KIND;
339
0
#if mxIntegerDivideOverflowException
340
0
    if ((x == (txInteger)0x80000000) && (y == -1))
341
0
      mxResult->value.integer = 0;
342
0
    else
343
0
#endif
344
0
      mxResult->value.integer = (x % y + y) % y;
345
0
  }
346
0
}
347
348
void fx_Math_imul(txMachine* the)
349
26.2k
{
350
26.2k
  txInteger x = (mxArgc > 0) ? fxToInteger(the, mxArgv(0)) : 0;
351
26.2k
  txInteger y = (mxArgc > 1) ? fxToInteger(the, mxArgv(1)) : 0;
352
26.2k
  mxResult->kind = XS_INTEGER_KIND;
353
26.2k
  mxResult->value.integer = x * y;
354
26.2k
}
355
356
void fx_Math_imuldiv(txMachine* the)
357
52.5k
{
358
52.5k
  txS8 x = (mxArgc > 0) ? fxToInteger(the, mxArgv(0)) : 0;
359
52.5k
  txS8 y = (mxArgc > 1) ? fxToInteger(the, mxArgv(1)) : 0;
360
52.5k
  txS8 z = (mxArgc > 2) ? fxToInteger(the, mxArgv(2)) : 0;
361
52.5k
  if (z == 0) {
362
26.3k
    mxResult->kind = XS_NUMBER_KIND;
363
26.3k
    mxResult->value.number = C_NAN;
364
26.3k
  }
365
26.1k
  else {
366
26.1k
    txS8 r = (x * y) / z;
367
26.1k
    mxResult->kind = XS_INTEGER_KIND;
368
26.1k
    mxResult->value.integer = (txInteger)(r & 0x00000000FFFFFFFF);
369
26.1k
  }
370
52.5k
}
371
372
void fx_Math_irandom(txMachine* the)
373
0
{
374
0
  double min = 0;
375
0
  double max = 2147483647;
376
0
  uint32_t result;
377
0
  if (mxArgc > 1) {
378
0
    min = (double)fxToInteger(the, mxArgv(0));
379
0
    max = (double)fxToInteger(the, mxArgv(1));
380
0
  }
381
0
  else if (mxArgc > 0) {
382
0
    max = (double)fxToInteger(the, mxArgv(0));
383
0
  }
384
0
  result = c_rand();
385
0
  while (result == C_RAND_MAX)
386
0
    result = c_rand();
387
0
  if (max < min)
388
0
    mxResult->value.integer = (txInteger)c_ceil(min + (((double)result / (double)C_RAND_MAX) * (max - min)));
389
0
  else
390
0
    mxResult->value.integer = (txInteger)c_floor(min + (((double)result / (double)C_RAND_MAX) * (max - min)));
391
0
  mxResult->kind = XS_INTEGER_KIND;
392
0
}
393
394
void fx_Math_irandom_secure(txMachine* the)
395
0
{
396
0
  mxTypeError("secure mode");
397
0
}
398
399
void fx_Math_irem(txMachine* the)
400
0
{
401
0
  txInteger x = (mxArgc > 0) ? fxToInteger(the, mxArgv(0)) : 0;
402
0
  txInteger y = (mxArgc > 1) ? fxToInteger(the, mxArgv(1)) : 0;
403
0
  if (y == 0) {
404
0
    mxResult->kind = XS_NUMBER_KIND;
405
0
    mxResult->value.number = C_NAN;
406
0
  }
407
0
  else {
408
0
    mxResult->kind = XS_INTEGER_KIND;
409
0
#if mxIntegerDivideOverflowException
410
0
    if ((x == (txInteger)0x80000000) && (y == -1))
411
0
      mxResult->value.integer = 0;
412
0
    else
413
0
#endif
414
0
      mxResult->value.integer = x % y;
415
0
  }
416
0
}
417
418
void fx_Math_log(txMachine* the)
419
21
{
420
21
  mxNanResultIfNoArg;
421
20
  fxToNumber(the, mxArgv(0));
422
20
  mxResult->kind = XS_NUMBER_KIND;
423
20
  mxResult->value.number = c_log(mxArgv(0)->value.number);
424
20
}
425
426
void fx_Math_log1p(txMachine* the)
427
997
{
428
997
  mxNanResultIfNoArg;
429
996
  fxToNumber(the, mxArgv(0));
430
996
  mxResult->kind = XS_NUMBER_KIND;
431
996
  mxResult->value.number = c_log1p(mxArgv(0)->value.number);
432
996
}
433
434
void fx_Math_log10(txMachine* the)
435
92
{
436
92
  mxNanResultIfNoArg;
437
91
  fxToNumber(the, mxArgv(0));
438
91
  mxResult->kind = XS_NUMBER_KIND;
439
91
  mxResult->value.number = c_log10(mxArgv(0)->value.number);
440
91
}
441
442
void fx_Math_log2(txMachine* the)
443
26
{
444
26
  mxNanResultIfNoArg;
445
26
  fxToNumber(the, mxArgv(0));
446
26
  mxResult->kind = XS_NUMBER_KIND;
447
#if mxAndroid
448
  mxResult->value.number = c_log(mxArgv(0)->value.number) / c_log(2);
449
#else
450
26
  mxResult->value.number = c_log2(mxArgv(0)->value.number);
451
26
#endif
452
26
}
453
454
void fx_Math_max(txMachine* the)
455
2.86k
{
456
2.86k
  txInteger c = mxArgc, i = 0;
457
2.86k
  mxResult->kind = XS_NUMBER_KIND;
458
2.86k
  mxResult->value.number = -((txNumber)C_INFINITY);
459
2.86k
  if (0 == c)
460
78
    return;
461
462
2.78k
  if (XS_INTEGER_KIND == mxArgv(0)->kind) {
463
1.99k
    mxResult->kind = XS_INTEGER_KIND;
464
1.99k
    mxResult->value.integer = mxArgv(0)->value.integer;
465
1.99k
    i = 1;
466
1.99k
  }
467
468
6.26k
  for (; i < c; i++) {
469
3.98k
    txSlot *slot = mxArgv(i);
470
3.98k
    if (XS_INTEGER_KIND == mxResult->kind) {
471
2.30k
      if (XS_INTEGER_KIND == slot->kind) {
472
1.59k
        if (mxResult->value.integer < slot->value.integer) {
473
951
          mxResult->value.integer = slot->value.integer;
474
951
        }
475
1.59k
        continue;
476
1.59k
      }
477
701
      mxResult->kind = XS_NUMBER_KIND;
478
701
      mxResult->value.number = mxResult->value.integer;
479
701
    }
480
481
2.38k
    txNumber n = fxToNumber(the, slot);
482
2.38k
    if (c_isnan(n)) {
483
1.68k
      for (; i < c; i++)
484
1.17k
        fxToNumber(the, mxArgv(i));
485
507
      mxResult->value.number = C_NAN;
486
507
      return;
487
507
    }
488
1.87k
    if (mxResult->value.number < n)
489
591
      mxResult->value.number = n;
490
1.28k
    else if ((mxResult->value.number == 0) && (n == 0)) {
491
637
      if (c_signbit(mxResult->value.number) != c_signbit(n))
492
420
        mxResult->value.number = 0;
493
637
    }
494
1.87k
  }
495
2.78k
}
496
497
void fx_Math_min(txMachine* the)
498
3.33k
{
499
3.33k
  txInteger c = mxArgc, i = 0;
500
3.33k
  mxResult->kind = XS_NUMBER_KIND;
501
3.33k
  mxResult->value.number = (txNumber)C_INFINITY;
502
3.33k
  if (0 == c)
503
1.75k
    return;
504
505
1.58k
  if (XS_INTEGER_KIND == mxArgv(0)->kind) {
506
883
    mxResult->kind = XS_INTEGER_KIND;
507
883
    mxResult->value.integer = mxArgv(0)->value.integer;
508
883
    i = 1;
509
883
  }
510
511
3.72k
  for (; i < c; i++) {
512
3.19k
    txSlot *slot = mxArgv(i);
513
3.19k
    if (XS_INTEGER_KIND == mxResult->kind) {
514
1.17k
      if (XS_INTEGER_KIND == slot->kind) {
515
512
        if (mxResult->value.integer > slot->value.integer)
516
233
          mxResult->value.integer = slot->value.integer;
517
512
        continue;
518
512
      }
519
658
      mxResult->kind = XS_NUMBER_KIND;
520
658
      mxResult->value.number = mxResult->value.integer;
521
658
    }
522
  
523
2.67k
    txNumber n = fxToNumber(the, slot);
524
2.67k
    if (c_isnan(n)) {
525
2.48k
      for (; i < c; i++)
526
1.42k
        fxToNumber(the, mxArgv(i));
527
1.05k
      mxResult->value.number = C_NAN;
528
1.05k
      return;
529
1.05k
    }
530
1.62k
    if (mxResult->value.number > n)
531
1.02k
      mxResult->value.number = n;
532
606
    else if ((mxResult->value.number == 0) && (n == 0)) {
533
210
      if (c_signbit(mxResult->value.number) != c_signbit(n))
534
80
        mxResult->value.number = -0.0;
535
210
    }
536
1.62k
  }
537
1.58k
}
538
539
void fx_Math_mod(txMachine* the)
540
0
{
541
0
  txNumber x = (mxArgc > 0) ? fxToNumber(the, mxArgv(0)) : 0;
542
0
  txNumber y = (mxArgc > 1) ? fxToNumber(the, mxArgv(1)) : 0;
543
0
  mxResult->kind = XS_NUMBER_KIND;
544
0
  mxResult->value.number = c_fmod((c_fmod(x, y) + y), y);
545
0
}
546
547
txNumber fx_pow(txNumber x, txNumber y)
548
3.23M
{
549
3.23M
  if (!c_isfinite(y) && (c_fabs(x) == 1.0))
550
574
    return C_NAN;
551
3.23M
  return c_pow(x, y);
552
3.23M
}
553
554
void fx_Math_pow(txMachine* the)
555
205k
{
556
205k
  txNumber x, y;
557
205k
  mxNanResultIfNoArg2;
558
157k
  x = fxToNumber(the, mxArgv(0));
559
157k
  y = fxToNumber(the, mxArgv(1));
560
157k
  mxResult->kind = XS_NUMBER_KIND;
561
157k
  mxResult->value.number = fx_pow(x, y);
562
157k
}
563
564
void fx_Math_random(txMachine* the)
565
56.9k
{
566
56.9k
  uint32_t result;
567
56.9k
  do {
568
56.9k
    result = c_rand();
569
56.9k
  } while (result == C_RAND_MAX);
570
56.9k
  mxResult->kind = XS_NUMBER_KIND;
571
56.9k
  mxResult->value.number = (double)result / (double)C_RAND_MAX;
572
56.9k
}
573
574
void fx_Math_random_secure(txMachine* the)
575
0
{
576
0
  mxTypeError("secure mode");
577
0
}
578
579
void fx_Math_round(txMachine* the)
580
13.8k
{
581
13.8k
    txNumber arg;
582
13.8k
  mxNanResultIfNoArg;
583
13.8k
  if (XS_INTEGER_KIND == mxArgv(0)->kind) {
584
1.03k
    mxResult->kind = XS_INTEGER_KIND;
585
1.03k
    mxResult->value.integer = mxArgv(0)->value.integer;
586
1.03k
    return;
587
1.03k
  }
588
12.8k
  arg = fxToNumber(the, mxArgv(0));
589
12.8k
  if (c_isnormal(arg) && (-4503599627370495 < arg) && (arg < 4503599627370495)) { // 2 ** 52 - 1
590
11.5k
    if ((arg < -0.5) || (0.5 <= arg))
591
9.29k
      arg = c_floor(arg + 0.5);
592
2.27k
    else if (arg < 0)
593
1.11k
      arg = -0.0;
594
1.15k
    else if (arg > 0)
595
1.15k
      arg = 0.0;
596
11.5k
    }
597
12.8k
  mxResult->kind = XS_NUMBER_KIND;
598
12.8k
  mxResult->value.number = arg;
599
12.8k
  fx_Math_toInteger(the);
600
12.8k
}
601
602
void fx_Math_sqrt(txMachine* the)
603
1.00k
{
604
1.00k
  mxNanResultIfNoArg;
605
1.00k
  fxToNumber(the, mxArgv(0));
606
1.00k
  mxResult->kind = XS_NUMBER_KIND;
607
1.00k
  mxResult->value.number = c_sqrt(mxArgv(0)->value.number);
608
1.00k
}
609
610
void fx_Math_sign(txMachine* the)
611
18.6k
{
612
18.6k
  txNumber arg;
613
18.6k
  mxNanResultIfNoArg;
614
17.9k
  arg = fxToNumber(the, mxArgv(0));
615
17.9k
  mxResult->kind = XS_NUMBER_KIND;
616
17.9k
  if (c_isnan(arg))
617
11.7k
    mxResult->value.number = C_NAN;
618
6.22k
  else if (arg < 0)
619
1.42k
    mxResult->value.number = -1;
620
4.79k
  else if (arg > 0)
621
1.50k
    mxResult->value.number = 1;
622
3.29k
  else
623
3.29k
    mxResult->value.number = arg;
624
17.9k
  fx_Math_toInteger(the);
625
17.9k
}
626
627
void fx_Math_sin(txMachine* the)
628
20.9k
{
629
20.9k
  mxNanResultIfNoArg;
630
19.4k
  fxToNumber(the, mxArgv(0));
631
19.4k
  mxResult->kind = XS_NUMBER_KIND;
632
19.4k
  mxResult->value.number = c_sin(mxArgv(0)->value.number);
633
19.4k
}
634
635
void fx_Math_sinh(txMachine* the)
636
295k
{
637
295k
  mxNanResultIfNoArg;
638
295k
  fxToNumber(the, mxArgv(0));
639
295k
  mxResult->kind = XS_NUMBER_KIND;
640
295k
  mxResult->value.number = c_sinh(mxArgv(0)->value.number);
641
295k
}
642
643
void fx_Math_tan(txMachine* the)
644
21.7k
{
645
21.7k
  mxNanResultIfNoArg;
646
21.6k
  fxToNumber(the, mxArgv(0));
647
21.6k
  mxResult->kind = XS_NUMBER_KIND;
648
21.6k
  mxResult->value.number = c_tan(mxArgv(0)->value.number);
649
21.6k
}
650
651
void fx_Math_tanh(txMachine* the)
652
7.70k
{
653
7.70k
  mxNanResultIfNoArg;
654
6.30k
  fxToNumber(the, mxArgv(0));
655
6.30k
  mxResult->kind = XS_NUMBER_KIND;
656
6.30k
  mxResult->value.number = c_tanh(mxArgv(0)->value.number);
657
6.30k
}
658
659
void fx_Math_trunc(txMachine* the)
660
220
{
661
220
  mxNanResultIfNoArg;
662
217
  fxToNumber(the, mxArgv(0));
663
217
  mxResult->kind = XS_NUMBER_KIND;
664
217
  mxResult->value.number = c_trunc(mxArgv(0)->value.number);
665
217
  fx_Math_toInteger(the);
666
217
}
667
668
void fx_Math_toInteger(txMachine* the)
669
428k
{
670
428k
  txNumber number = mxResult->value.number;
671
428k
  txInteger integer = (txInteger)number;
672
428k
  txNumber check = integer;
673
428k
  if ((number == check) && (number || !c_signbit(number))) {
674
270k
    mxResult->value.integer = integer;
675
270k
    mxResult->kind = XS_INTEGER_KIND;
676
270k
  }
677
428k
}