Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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