Skip to content

HTTPS clone URL

Subversion checkout URL

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