Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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