Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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.