Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 729 lines (636 sloc) 15.811 kB
9595725 update copyrights to 2011
Laurent Sansonetti authored
1 /*
2 * This file is covered by the Ruby license. See COPYING for more details.
3 *
4 * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
5 * Copyright (C) 1993-2007 Yukihiro Matsumoto
6 */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
7
d0898dd include/ruby/macruby.h -> macruby_internal.h
Laurent Sansonetti authored
8 #include "macruby_internal.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
9 #include <math.h>
10 #include <errno.h>
11
12 VALUE rb_mMath;
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
13 VALUE rb_eMathDomainError;
14
15 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
16 #define domain_error(msg) \
17 rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
18
19 static VALUE
20 to_flo(VALUE x)
21 {
8397cfb a quick optimization
Laurent Sansonetti authored
22 if (CLASS_OF(x) == rb_cFloat) {
23 return x;
24 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
25 if (!rb_obj_is_kind_of(x, rb_cNumeric)) {
26 rb_raise(rb_eTypeError, "can't convert %s into Float",
27 NIL_P(x) ? "nil" :
28 x == Qtrue ? "true" :
29 x == Qfalse ? "false" :
30 rb_obj_classname(x));
31 }
32 return rb_convert_type(x, T_FLOAT, "Float", "to_f");
33 }
34
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
35 #define Need_Float(x) do {if (TYPE(x) != T_FLOAT) {(x) = to_flo(x);}} while(0)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
36 #define Need_Float2(x,y) do {\
37 Need_Float(x);\
38 Need_Float(y);\
39 } while (0)
40
41 /*
42 * call-seq:
43 * Math.atan2(y, x) => float
44 *
45 * Computes the arc tangent given <i>y</i> and <i>x</i>. Returns
46 * -PI..PI.
47 *
48 */
49
50 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
51 math_atan2(VALUE obj, SEL sel, VALUE y, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
52 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
53 double dx, dy;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
54 Need_Float2(y, x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
55 dx = RFLOAT_VALUE(x);
56 dy = RFLOAT_VALUE(y);
57 if (dx == 0.0 && dy == 0.0) {
58 domain_error("atan2");
59 }
60 if (isinf(dx) && isinf(dy)) {
61 domain_error("atan2");
62 }
63 return DBL2NUM(atan2(dy, dx));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
64 }
65
66
67 /*
68 * call-seq:
69 * Math.cos(x) => float
70 *
71 * Computes the cosine of <i>x</i> (expressed in radians). Returns
72 * -1..1.
73 */
74
75 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
76 math_cos(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
77 {
78 Need_Float(x);
79 return DOUBLE2NUM(cos(RFLOAT_VALUE(x)));
80 }
81
82 /*
83 * call-seq:
84 * Math.sin(x) => float
85 *
86 * Computes the sine of <i>x</i> (expressed in radians). Returns
87 * -1..1.
88 */
89
90 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
91 math_sin(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
92 {
93 Need_Float(x);
94
95 return DOUBLE2NUM(sin(RFLOAT_VALUE(x)));
96 }
97
98
99 /*
100 * call-seq:
101 * Math.tan(x) => float
102 *
103 * Returns the tangent of <i>x</i> (expressed in radians).
104 */
105
106 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
107 math_tan(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
108 {
109 Need_Float(x);
110
111 return DOUBLE2NUM(tan(RFLOAT_VALUE(x)));
112 }
113
114 /*
115 * call-seq:
116 * Math.acos(x) => float
117 *
118 * Computes the arc cosine of <i>x</i>. Returns 0..PI.
119 */
120
121 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
122 math_acos(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
123 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
124 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
125
126 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
127 d0 = RFLOAT_VALUE(x);
128 /* check for domain error */
129 if (d0 < -1.0 || 1.0 < d0) {
130 domain_error("acos");
131 }
132 d = acos(d0);
133 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
134 }
135
136 /*
137 * call-seq:
138 * Math.asin(x) => float
139 *
140 * Computes the arc sine of <i>x</i>. Returns -{PI/2} .. {PI/2}.
141 */
142
143 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
144 math_asin(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
145 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
146 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
147
148 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
149 d0 = RFLOAT_VALUE(x);
150 /* check for domain error */
151 if (d0 < -1.0 || 1.0 < d0) {
152 domain_error("asin");
153 }
154 d = asin(d0);
155 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
156 }
157
158 /*
159 * call-seq:
160 * Math.atan(x) => float
161 *
162 * Computes the arc tangent of <i>x</i>. Returns -{PI/2} .. {PI/2}.
163 */
164
165 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
166 math_atan(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
167 {
168 Need_Float(x);
169 return DOUBLE2NUM(atan(RFLOAT_VALUE(x)));
170 }
171
172 #ifndef HAVE_COSH
173 double
174 cosh(double x)
175 {
176 return (exp(x) + exp(-x)) / 2;
177 }
178 #endif
179
180 /*
181 * call-seq:
182 * Math.cosh(x) => float
183 *
184 * Computes the hyperbolic cosine of <i>x</i> (expressed in radians).
185 */
186
187 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
188 math_cosh(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
189 {
190 Need_Float(x);
191
192 return DOUBLE2NUM(cosh(RFLOAT_VALUE(x)));
193 }
194
195 #ifndef HAVE_SINH
196 double
197 sinh(double x)
198 {
199 return (exp(x) - exp(-x)) / 2;
200 }
201 #endif
202
203 /*
204 * call-seq:
205 * Math.sinh(x) => float
206 *
207 * Computes the hyperbolic sine of <i>x</i> (expressed in
208 * radians).
209 */
210
211 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
212 math_sinh(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
213 {
214 Need_Float(x);
215 return DOUBLE2NUM(sinh(RFLOAT_VALUE(x)));
216 }
217
218 #ifndef HAVE_TANH
219 double
220 tanh(double x)
221 {
222 return sinh(x) / cosh(x);
223 }
224 #endif
225
226 /*
227 * call-seq:
228 * Math.tanh() => float
229 *
230 * Computes the hyperbolic tangent of <i>x</i> (expressed in
231 * radians).
232 */
233
234 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
235 math_tanh(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
236 {
237 Need_Float(x);
238 return DOUBLE2NUM(tanh(RFLOAT_VALUE(x)));
239 }
240
241 /*
242 * call-seq:
243 * Math.acosh(x) => float
244 *
245 * Computes the inverse hyperbolic cosine of <i>x</i>.
246 */
247
248 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
249 math_acosh(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
250 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
251 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
252
253 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
254 d0 = RFLOAT_VALUE(x);
255 /* check for domain error */
256 if (d0 < 1.0) {
257 domain_error("acosh");
258 }
259 d = acosh(d0);
260 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
261 }
262
263 /*
264 * call-seq:
265 * Math.asinh(x) => float
266 *
267 * Computes the inverse hyperbolic sine of <i>x</i>.
268 */
269
270 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
271 math_asinh(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
272 {
273 Need_Float(x);
274 return DOUBLE2NUM(asinh(RFLOAT_VALUE(x)));
275 }
276
277 /*
278 * call-seq:
279 * Math.atanh(x) => float
280 *
281 * Computes the inverse hyperbolic tangent of <i>x</i>.
282 */
283
284 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
285 math_atanh(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
286 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
287 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
288
289 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
290 d0 = RFLOAT_VALUE(x);
291 /* check for domain error */
292 if (d0 < -1.0 || +1.0 < d0) {
293 domain_error("atanh");
294 }
295 /* check for pole error */
296 if (d0 == -1.0) return DBL2NUM(-INFINITY);
297 if (d0 == +1.0) return DBL2NUM(+INFINITY);
298 d = atanh(d0);
299 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
300 }
301
302 /*
303 * call-seq:
304 * Math.exp(x) => float
305 *
306 * Returns e**x.
307 */
308
309 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
310 math_exp(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
311 {
312 Need_Float(x);
313 return DOUBLE2NUM(exp(RFLOAT_VALUE(x)));
314 }
315
316 /*
317 * call-seq:
318 * Math.log(numeric) => float
319 * Math.log(num,base) => float
320 *
321 * Returns the natural logarithm of <i>numeric</i>.
322 * If additional second argument is given, it will be the base
323 * of logarithm.
324 */
325
326 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
327 math_log(VALUE rcv, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
328 {
329 VALUE x, base;
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
330 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
331
332 rb_scan_args(argc, argv, "11", &x, &base);
333 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
334 d0 = RFLOAT_VALUE(x);
335 /* check for domain error */
336 if (d0 < 0.0) {
337 domain_error("log");
338 }
339 /* check for pole error */
340 if (d0 == 0.0) {
341 return DBL2NUM(-INFINITY);
342 }
343 d = log(d0);
344 if (argc == 2) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
345 Need_Float(base);
346 d /= log(RFLOAT_VALUE(base));
347 }
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
348 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
349 }
350
351 #ifndef log2
352 #ifndef HAVE_LOG2
353 double
354 log2(double x)
355 {
356 return log10(x)/log10(2.0);
357 }
358 #else
359 extern double log2(double);
360 #endif
361 #endif
362
363 /*
364 * call-seq:
365 * Math.log2(numeric) => float
366 *
367 * Returns the base 2 logarithm of <i>numeric</i>.
368 */
369
370 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
371 math_log2(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
372 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
373 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
374
375 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
376 d0 = RFLOAT_VALUE(x);
377 /* check for domain error */
378 if (d0 < 0.0) {
379 domain_error("log2");
380 }
381 /* check for pole error */
382 if (d0 == 0.0) {
383 return DBL2NUM(-INFINITY);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
384 }
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
385 d = log2(d0);
386 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
387 }
388
389 /*
390 * call-seq:
391 * Math.log10(numeric) => float
392 *
393 * Returns the base 10 logarithm of <i>numeric</i>.
394 */
395
396 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
397 math_log10(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
398 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
399 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
400
401 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
402 d0 = RFLOAT_VALUE(x);
403 /* check for domain error */
404 if (d0 < 0.0) {
405 domain_error("log10");
406 }
407 /* check for pole error */
408 if (d0 == 0.0) {
409 return DBL2NUM(-INFINITY);
410 }
411 d = log10(d0);
412 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
413 }
414
415 /*
416 * call-seq:
417 * Math.sqrt(numeric) => float
418 *
419 * Returns the non-negative square root of <i>numeric</i>.
420 */
421
422 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
423 math_sqrt(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
424 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
425 double d0, d;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
426
427 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
428 d0 = RFLOAT_VALUE(x);
429 /* check for domain error */
430 if (d0 < 0.0) {
431 domain_error("sqrt");
432 }
433 if (d0 == 0.0) {
434 return DBL2NUM(0.0);
435 }
436 d = sqrt(d0);
437 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
438 }
439
440 /*
441 * call-seq:
442 * Math.cbrt(numeric) => float
443 *
444 * Returns the cube root of <i>numeric</i>.
445 */
446
447 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
448 math_cbrt(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
449 {
450 Need_Float(x);
451 return DOUBLE2NUM(cbrt(RFLOAT_VALUE(x)));
452 }
453
454 /*
455 * call-seq:
456 * Math.frexp(numeric) => [ fraction, exponent ]
457 *
458 * Returns a two-element array containing the normalized fraction (a
459 * <code>Float</code>) and exponent (a <code>Fixnum</code>) of
460 * <i>numeric</i>.
461 *
462 * fraction, exponent = Math.frexp(1234) #=> [0.6025390625, 11]
463 * fraction * 2**exponent #=> 1234.0
464 */
465
466 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
467 math_frexp(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
468 {
469 double d;
470 int exp;
471
472 Need_Float(x);
473
474 d = frexp(RFLOAT_VALUE(x), &exp);
475 return rb_assoc_new(DOUBLE2NUM(d), INT2NUM(exp));
476 }
477
478 /*
479 * call-seq:
480 * Math.ldexp(flt, int) -> float
481 *
482 * Returns the value of <i>flt</i>*(2**<i>int</i>).
483 *
484 * fraction, exponent = Math.frexp(1234)
485 * Math.ldexp(fraction, exponent) #=> 1234.0
486 */
487
488 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
489 math_ldexp(VALUE obj, SEL sel, VALUE x, VALUE n)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
490 {
491 Need_Float(x);
492 return DOUBLE2NUM(ldexp(RFLOAT_VALUE(x), NUM2INT(n)));
493 }
494
495 /*
496 * call-seq:
497 * Math.hypot(x, y) => float
498 *
499 * Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle
500 * with sides <i>x</i> and <i>y</i>.
501 *
502 * Math.hypot(3, 4) #=> 5.0
503 */
504
505 VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
506 math_hypot(VALUE obj, SEL sel, VALUE x, VALUE y)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
507 {
508 Need_Float2(x, y);
509 return DOUBLE2NUM(hypot(RFLOAT_VALUE(x), RFLOAT_VALUE(y)));
510 }
511
512 /*
513 * call-seq:
514 * Math.erf(x) => float
515 *
516 * Calculates the error function of x.
517 */
518
519 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
520 math_erf(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
521 {
522 Need_Float(x);
523 return DOUBLE2NUM(erf(RFLOAT_VALUE(x)));
524 }
525
526 /*
527 * call-seq:
528 * Math.erfc(x) => float
529 *
530 * Calculates the complementary error function of x.
531 */
532
533 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
534 math_erfc(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
535 {
536 Need_Float(x);
537 return DOUBLE2NUM(erfc(RFLOAT_VALUE(x)));
538 }
539
540 /*
541 * call-seq:
542 * Math.gamma(x) => float
543 *
544 * Calculates the gamma function of x.
545 *
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
546 * Note that gamma(n) is same as fact(n-1) for integer n > 0.
547 * However gamma(n) returns float and can be an approximation.
9c1d230 committing experimental branch content
Laurent Sansonetti authored
548 *
549 * def fact(n) (1..n).inject(1) {|r,i| r*i } end
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
550 * 1.upto(26) {|i| p [i, Math.gamma(i), fact(i-1)] }
551 * #=> [1, 1.0, 1]
552 * # [2, 1.0, 1]
553 * # [3, 2.0, 2]
554 * # [4, 6.0, 6]
555 * # [5, 24.0, 24]
556 * # [6, 120.0, 120]
557 * # [7, 720.0, 720]
558 * # [8, 5040.0, 5040]
559 * # [9, 40320.0, 40320]
560 * # [10, 362880.0, 362880]
561 * # [11, 3628800.0, 3628800]
562 * # [12, 39916800.0, 39916800]
563 * # [13, 479001600.0, 479001600]
564 * # [14, 6227020800.0, 6227020800]
565 * # [15, 87178291200.0, 87178291200]
566 * # [16, 1307674368000.0, 1307674368000]
567 * # [17, 20922789888000.0, 20922789888000]
568 * # [18, 355687428096000.0, 355687428096000]
569 * # [19, 6.402373705728e+15, 6402373705728000]
570 * # [20, 1.21645100408832e+17, 121645100408832000]
571 * # [21, 2.43290200817664e+18, 2432902008176640000]
572 * # [22, 5.109094217170944e+19, 51090942171709440000]
573 * # [23, 1.1240007277776077e+21, 1124000727777607680000]
574 * # [24, 2.5852016738885062e+22, 25852016738884976640000]
575 * # [25, 6.204484017332391e+23, 620448401733239439360000]
576 * # [26, 1.5511210043330954e+25, 15511210043330985984000000]
9c1d230 committing experimental branch content
Laurent Sansonetti authored
577 *
578 */
579
580 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
581 math_gamma(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
582 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
583 static const double fact_table[] = {
584 /* fact(0) */ 1.0,
585 /* fact(1) */ 1.0,
586 /* fact(2) */ 2.0,
587 /* fact(3) */ 6.0,
588 /* fact(4) */ 24.0,
589 /* fact(5) */ 120.0,
590 /* fact(6) */ 720.0,
591 /* fact(7) */ 5040.0,
592 /* fact(8) */ 40320.0,
593 /* fact(9) */ 362880.0,
594 /* fact(10) */ 3628800.0,
595 /* fact(11) */ 39916800.0,
596 /* fact(12) */ 479001600.0,
597 /* fact(13) */ 6227020800.0,
598 /* fact(14) */ 87178291200.0,
599 /* fact(15) */ 1307674368000.0,
600 /* fact(16) */ 20922789888000.0,
601 /* fact(17) */ 355687428096000.0,
602 /* fact(18) */ 6402373705728000.0,
603 /* fact(19) */ 121645100408832000.0,
604 /* fact(20) */ 2432902008176640000.0,
605 /* fact(21) */ 51090942171709440000.0,
606 /* fact(22) */ 1124000727777607680000.0,
607 /* fact(23)=25852016738884976640000 needs 56bit mantissa which is
608 * impossible to represent exactly in IEEE 754 double which have
609 * 53bit mantissa. */
610 };
611 double d0, d;
612 double intpart, fracpart;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
613 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
614 d0 = RFLOAT_VALUE(x);
615 /* check for domain error */
616 if (isinf(d0) && signbit(d0)) {
617 domain_error("gamma");
618 }
619 fracpart = modf(d0, &intpart);
620 if (fracpart == 0.0) {
621 if (intpart < 0) {
622 domain_error("gamma");
623 }
624 if (0 < intpart &&
625 intpart - 1 < (double)numberof(fact_table)) {
626 return DBL2NUM(fact_table[(int)intpart - 1]);
627 }
628 }
629 d = tgamma(d0);
630 return DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
631 }
632
633 /*
634 * call-seq:
635 * Math.lgamma(x) => [float, -1 or 1]
636 *
637 * Calculates the logarithmic gamma of x and
638 * the sign of gamma of x.
639 *
640 * Math.lgamma(x) is same as
641 * [Math.log(Math.gamma(x).abs), Math.gamma(x) < 0 ? -1 : 1]
642 * but avoid overflow by Math.gamma(x) for large x.
643 */
644
645 #include "lgamma_r.c"
646
647 static VALUE
38078c0 ported the math.c apis to the new runtime
Laurent Sansonetti authored
648 math_lgamma(VALUE obj, SEL sel, VALUE x)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
649 {
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
650 double d0, d;
651 int sign = 1;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
652 VALUE v;
653 Need_Float(x);
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
654 d0 = RFLOAT_VALUE(x);
655 /* check for domain error */
656 if (isinf(d0)) {
657 if (signbit(d0)) {
658 domain_error("lgamma");
659 }
660 return rb_assoc_new(DBL2NUM(INFINITY), INT2FIX(1));
661 }
662 d = lgamma_r(d0, &sign);
663 v = DBL2NUM(d);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
664 return rb_assoc_new(v, INT2FIX(sign));
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
665
9c1d230 committing experimental branch content
Laurent Sansonetti authored
666 }
667
668 /*
669 * The <code>Math</code> module contains module functions for basic
670 * trigonometric and transcendental functions. See class
671 * <code>Float</code> for a list of constants that
672 * define Ruby's floating point accuracy.
673 */
674
675
676 void
677 Init_Math(void)
678 {
679 rb_mMath = rb_define_module("Math");
7b2ff65 Improve core/math passing rate (backported ruby19 changes)
Thibault Martin-Lagardette authored
680 rb_eMathDomainError = rb_define_class_under(rb_mMath, "DomainError", rb_eStandardError);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
681
682 #ifdef M_PI
683 rb_define_const(rb_mMath, "PI", DOUBLE2NUM(M_PI));
684 #else
685 rb_define_const(rb_mMath, "PI", DOUBLE2NUM(atan(1.0)*4.0));
686 #endif
687
688 #ifdef M_E
689 rb_define_const(rb_mMath, "E", DOUBLE2NUM(M_E));
690 #else
691 rb_define_const(rb_mMath, "E", DOUBLE2NUM(exp(1.0)));
692 #endif
693
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
694 rb_objc_define_module_function(rb_mMath, "atan2", math_atan2, 2);
695 rb_objc_define_module_function(rb_mMath, "cos", math_cos, 1);
696 rb_objc_define_module_function(rb_mMath, "sin", math_sin, 1);
697 rb_objc_define_module_function(rb_mMath, "tan", math_tan, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
698
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
699 rb_objc_define_module_function(rb_mMath, "acos", math_acos, 1);
700 rb_objc_define_module_function(rb_mMath, "asin", math_asin, 1);
701 rb_objc_define_module_function(rb_mMath, "atan", math_atan, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
702
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
703 rb_objc_define_module_function(rb_mMath, "cosh", math_cosh, 1);
704 rb_objc_define_module_function(rb_mMath, "sinh", math_sinh, 1);
705 rb_objc_define_module_function(rb_mMath, "tanh", math_tanh, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
706
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
707 rb_objc_define_module_function(rb_mMath, "acosh", math_acosh, 1);
708 rb_objc_define_module_function(rb_mMath, "asinh", math_asinh, 1);
709 rb_objc_define_module_function(rb_mMath, "atanh", math_atanh, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
710
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
711 rb_objc_define_module_function(rb_mMath, "exp", math_exp, 1);
712 rb_objc_define_module_function(rb_mMath, "log", math_log, -1);
713 rb_objc_define_module_function(rb_mMath, "log2", math_log2, 1);
714 rb_objc_define_module_function(rb_mMath, "log10", math_log10, 1);
715 rb_objc_define_module_function(rb_mMath, "sqrt", math_sqrt, 1);
716 rb_objc_define_module_function(rb_mMath, "cbrt", math_cbrt, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
717
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
718 rb_objc_define_module_function(rb_mMath, "frexp", math_frexp, 1);
719 rb_objc_define_module_function(rb_mMath, "ldexp", math_ldexp, 2);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
720
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
721 rb_objc_define_module_function(rb_mMath, "hypot", math_hypot, 2);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
722
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
723 rb_objc_define_module_function(rb_mMath, "erf", math_erf, 1);
724 rb_objc_define_module_function(rb_mMath, "erfc", math_erfc, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
725
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
726 rb_objc_define_module_function(rb_mMath, "gamma", math_gamma, 1);
727 rb_objc_define_module_function(rb_mMath, "lgamma", math_lgamma, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
728 }
Something went wrong with that request. Please try again.