Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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.