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