Skip to content
This repository
Newer
Older
100644 728 lines (636 sloc) 15.811 kb
95957256 » Laurent Sansonetti
2011-01-15 update copyrights to 2011
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 */
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
7
d0898dd2 » Laurent Sansonetti
2011-01-08 include/ruby/macruby.h -> macruby_internal.h
8 #include "macruby_internal.h"
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
9 #include <math.h>
10 #include <errno.h>
11
12 VALUE rb_mMath;
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
18
19 static VALUE
20 to_flo(VALUE x)
21 {
8397cfbb » Laurent Sansonetti
2009-08-04 a quick optimization
22 if (CLASS_OF(x) == rb_cFloat) {
23 return x;
24 }
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
35 #define Need_Float(x) do {if (TYPE(x) != T_FLOAT) {(x) = to_flo(x);}} while(0)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
51 math_atan2(VALUE obj, SEL sel, VALUE y, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
52 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
53 double dx, dy;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
54 Need_Float2(y, x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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));
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
76 math_cos(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
91 math_sin(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
107 math_tan(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
122 math_acos(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
123 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
124 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
125
126 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
144 math_asin(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
145 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
146 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
147
148 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
166 math_atan(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
188 math_cosh(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
212 math_sinh(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
235 math_tanh(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
249 math_acosh(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
250 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
251 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
252
253 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
271 math_asinh(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
285 math_atanh(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
286 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
287 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
288
289 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
300 }
301
302 /*
303 * call-seq:
304 * Math.exp(x) => float
305 *
306 * Returns e**x.
307 */
308
309 VALUE
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
310 math_exp(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
327 math_log(VALUE rcv, SEL sel, int argc, VALUE *argv)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
328 {
329 VALUE x, base;
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
330 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
331
332 rb_scan_args(argc, argv, "11", &x, &base);
333 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
345 Need_Float(base);
346 d /= log(RFLOAT_VALUE(base));
347 }
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
348 return DBL2NUM(d);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
371 math_log2(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
372 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
373 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
374
375 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
384 }
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
385 d = log2(d0);
386 return DBL2NUM(d);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
397 math_log10(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
398 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
399 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
400
401 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
423 math_sqrt(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
424 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
425 double d0, d;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
426
427 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
448 math_cbrt(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
467 math_frexp(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
489 math_ldexp(VALUE obj, SEL sel, VALUE x, VALUE n)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
506 math_hypot(VALUE obj, SEL sel, VALUE x, VALUE y)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
520 math_erf(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
534 math_erfc(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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 *
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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.
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
548 *
549 * def fact(n) (1..n).inject(1) {|r,i| r*i } end
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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]
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
577 *
578 */
579
580 static VALUE
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
581 math_gamma(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
582 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
613 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
38078c08 » Laurent Sansonetti
2009-05-28 ported the math.c apis to the new runtime
648 math_lgamma(VALUE obj, SEL sel, VALUE x)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
649 {
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
650 double d0, d;
651 int sign = 1;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
652 VALUE v;
653 Need_Float(x);
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
664 return rb_assoc_new(v, INT2FIX(sign));
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
665
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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");
7b2ff650 » Thibault Martin-Lagardette
2010-05-14 Improve core/math passing rate (backported ruby19 changes)
680 rb_eMathDomainError = rb_define_class_under(rb_mMath, "DomainError", rb_eStandardError);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
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
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
698
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
702
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
706
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
710
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
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);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
717
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
718 rb_objc_define_module_function(rb_mMath, "frexp", math_frexp, 1);
719 rb_objc_define_module_function(rb_mMath, "ldexp", math_ldexp, 2);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
720
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
721 rb_objc_define_module_function(rb_mMath, "hypot", math_hypot, 2);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
722
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
723 rb_objc_define_module_function(rb_mMath, "erf", math_erf, 1);
724 rb_objc_define_module_function(rb_mMath, "erfc", math_erfc, 1);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
725
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
726 rb_objc_define_module_function(rb_mMath, "gamma", math_gamma, 1);
727 rb_objc_define_module_function(rb_mMath, "lgamma", math_lgamma, 1);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
728 }
Something went wrong with that request. Please try again.