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