Module: Math

Defined in:
math.c

Overview

The Math module contains module functions for basic trigonometric and transcendental functions. See class Float for a list of constants that define Ruby’s floating point accuracy.

Domains and codomains are given only for real (not complex) numbers.

Defined Under Namespace

Classes: DomainError

Constant Summary collapse

PI =

Definition of the mathematical constant PI as a Float number.

DBL2NUM(atan(1.0)*4.0)
E =

Definition of the mathematical constant E (e) as a Float number.

DBL2NUM(exp(1.0))

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.acos(x) ⇒ Float

Computes the arc cosine of x. Returns 0..PI.

Domain: [-1, 1]

Codomain: [0, PI]

Math.acos(0) == Math::PI/2  #=> true

Returns:



163
164
165
166
167
168
169
170
171
172
173
174
# File 'math.c', line 163

static VALUE
math_acos(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < -1.0 || 1.0 < d0) domain_error("acos");
    d = acos(d0);
    return DBL2NUM(d);
}

.acosh(x) ⇒ Float

Computes the inverse hyperbolic cosine of x.

Domain: [1, INFINITY)

Codomain: [0, INFINITY)

Math.acosh(1) #=> 0.0

Returns:



323
324
325
326
327
328
329
330
331
332
333
334
# File 'math.c', line 323

static VALUE
math_acosh(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 1.0) domain_error("acosh");
    d = acosh(d0);
    return DBL2NUM(d);
}

.asin(x) ⇒ Float

Computes the arc sine of x. Returns -PI/2..PI/2.

Domain: [-1, -1]

Codomain: [-PI/2, PI/2]

Math.asin(1) == Math::PI/2  #=> true

Returns:



189
190
191
192
193
194
195
196
197
198
199
200
# File 'math.c', line 189

static VALUE
math_asin(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < -1.0 || 1.0 < d0) domain_error("asin");
    d = asin(d0);
    return DBL2NUM(d);
}

.asinh(x) ⇒ Float

Computes the inverse hyperbolic sine of x.

Domain: (-INFINITY, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.asinh(1) #=> 0.881373587019543

Returns:



350
351
352
353
354
355
# File 'math.c', line 350

static VALUE
math_asinh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(asinh(RFLOAT_VALUE(x)));
}

.atan(x) ⇒ Float

Computes the arc tangent of x. Returns -PI/2..PI/2.

Domain: (-INFINITY, INFINITY)

Codomain: (-PI/2, PI/2)

Math.atan(0) #=> 0.0

Returns:



215
216
217
218
219
220
# File 'math.c', line 215

static VALUE
math_atan(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(atan(RFLOAT_VALUE(x)));
}

.atan2(y, x) ⇒ Float

Computes the arc tangent given y and x. Returns a Float in the range -PI..PI.

Domain: (-INFINITY, INFINITY)

Codomain: [-PI, PI]

Math.atan2(-0.0, -1.0) #=> -3.141592653589793
Math.atan2(-1.0, -1.0) #=> -2.356194490192345
Math.atan2(-1.0, 0.0)  #=> -1.5707963267948966
Math.atan2(-1.0, 1.0)  #=> -0.7853981633974483
Math.atan2(-0.0, 1.0)  #=> -0.0
Math.atan2(0.0, 1.0)   #=> 0.0
Math.atan2(1.0, 1.0)   #=> 0.7853981633974483
Math.atan2(1.0, 0.0)   #=> 1.5707963267948966
Math.atan2(1.0, -1.0)  #=> 2.356194490192345
Math.atan2(0.0, -1.0)  #=> 3.141592653589793

Returns:



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'math.c', line 61

static VALUE
math_atan2(VALUE obj, VALUE y, VALUE x)
{
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
    double dx, dy;
    Need_Float2(y, x);
    dx = RFLOAT_VALUE(x);
    dy = RFLOAT_VALUE(y);
    if (dx == 0.0 && dy == 0.0) {
	if (!signbit(dx))
	    return DBL2NUM(dy);
        if (!signbit(dy))
	    return DBL2NUM(M_PI);
	return DBL2NUM(-M_PI);
    }
    if (isinf(dx) && isinf(dy)) domain_error("atan2");
    return DBL2NUM(atan2(dy, dx));
}

.atanh(x) ⇒ Float

Computes the inverse hyperbolic tangent of x.

Domain: (-1, 1)

Codomain: (-INFINITY, INFINITY)

Math.atanh(1) #=> Infinity

Returns:



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'math.c', line 371

static VALUE
math_atanh(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 <  -1.0 || +1.0 <  d0) domain_error("atanh");
    /* check for pole error */
    if (d0 == -1.0) return DBL2NUM(-INFINITY);
    if (d0 == +1.0) return DBL2NUM(+INFINITY);
    d = atanh(d0);
    return DBL2NUM(d);
}

.cbrt(x) ⇒ Float

Returns the cube root of x.

Domain: [0, INFINITY)

Codomain:[0, INFINITY)

-9.upto(9) {|x|
  p [x, Math.cbrt(x), Math.cbrt(x)**3]
}
#=> [-9, -2.0800838230519, -9.0]
#   [-8, -2.0, -8.0]
#   [-7, -1.91293118277239, -7.0]
#   [-6, -1.81712059283214, -6.0]
#   [-5, -1.7099759466767, -5.0]
#   [-4, -1.5874010519682, -4.0]
#   [-3, -1.44224957030741, -3.0]
#   [-2, -1.25992104989487, -2.0]
#   [-1, -1.0, -1.0]
#   [0, 0.0, 0.0]
#   [1, 1.0, 1.0]
#   [2, 1.25992104989487, 2.0]
#   [3, 1.44224957030741, 3.0]
#   [4, 1.5874010519682, 4.0]
#   [5, 1.7099759466767, 5.0]
#   [6, 1.81712059283214, 6.0]
#   [7, 1.91293118277239, 7.0]
#   [8, 2.0, 8.0]
#   [9, 2.0800838230519, 9.0]

Returns:



647
648
649
650
651
652
# File 'math.c', line 647

static VALUE
math_cbrt(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(cbrt(RFLOAT_VALUE(x)));
}

.cos(x) ⇒ Float

Computes the cosine of x (expressed in radians). Returns a Float in the range -1.0..1.0.

Domain: (-INFINITY, INFINITY)

Codomain: [-1, 1]

Math.cos(Math::PI) #=> -1.0

Returns:



98
99
100
101
102
103
# File 'math.c', line 98

static VALUE
math_cos(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(cos(RFLOAT_VALUE(x)));
}

.cosh(x) ⇒ Float

Computes the hyperbolic cosine of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: [1, INFINITY)

Math.cosh(0) #=> 1.0

Returns:



244
245
246
247
248
249
# File 'math.c', line 244

static VALUE
math_cosh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(cosh(RFLOAT_VALUE(x)));
}

.erf(x) ⇒ Float

Calculates the error function of x.

Domain: (-INFINITY, INFINITY)

Codomain: (-1, 1)

  Math.erf(0) #=> 0.0

Returns:



725
726
727
728
729
730
# File 'math.c', line 725

static VALUE
math_erf(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(erf(RFLOAT_VALUE(x)));
}

.erfc(x) ⇒ Float

Calculates the complementary error function of x.

Domain: (-INFINITY, INFINITY)

Codomain: (0, 2)

  Math.erfc(0) #=> 1.0

Returns:



746
747
748
749
750
751
# File 'math.c', line 746

static VALUE
math_erfc(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(erfc(RFLOAT_VALUE(x)));
}

.exp(x) ⇒ Float

Returns e**x.

Domain: (-INFINITY, INFINITY)

Codomain: (0, INFINITY)

Math.exp(0)       #=> 1.0
Math.exp(1)       #=> 2.718281828459045
Math.exp(1.5)     #=> 4.4816890703380645

Returns:



403
404
405
406
407
408
# File 'math.c', line 403

static VALUE
math_exp(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(exp(RFLOAT_VALUE(x)));
}

.frexp(x) ⇒ Array

Returns a two-element array containing the normalized fraction (a Float) and exponent (a Fixnum) of x.

fraction, exponent = Math.frexp(1234)   #=> [0.6025390625, 11]
fraction * 2**exponent                  #=> 1234.0

Returns:



665
666
667
668
669
670
671
672
673
674
675
# File 'math.c', line 665

static VALUE
math_frexp(VALUE obj, VALUE x)
{
    double d;
    int exp;

    Need_Float(x);

    d = frexp(RFLOAT_VALUE(x), &exp);
    return rb_assoc_new(DBL2NUM(d), INT2NUM(exp));
}

.gamma(x) ⇒ Float

Calculates the gamma function of x.

Note that gamma(n) is same as fact(n-1) for integer n > 0.
However gamma(n) returns float and can be an approximation.

 def fact(n) (1..n).inject(1) {|r,i| r*i } end
 1.upto(26) {|i| p [i, Math.gamma(i), fact(i-1)] }
 #=> [1, 1.0, 1]
 #   [2, 1.0, 1]
 #   [3, 2.0, 2]
 #   [4, 6.0, 6]
 #   [5, 24.0, 24]
 #   [6, 120.0, 120]
 #   [7, 720.0, 720]
 #   [8, 5040.0, 5040]
 #   [9, 40320.0, 40320]
 #   [10, 362880.0, 362880]
 #   [11, 3628800.0, 3628800]
 #   [12, 39916800.0, 39916800]
 #   [13, 479001600.0, 479001600]
 #   [14, 6227020800.0, 6227020800]
 #   [15, 87178291200.0, 87178291200]
 #   [16, 1307674368000.0, 1307674368000]
 #   [17, 20922789888000.0, 20922789888000]
 #   [18, 355687428096000.0, 355687428096000]
 #   [19, 6.402373705728e+15, 6402373705728000]
 #   [20, 1.21645100408832e+17, 121645100408832000]
 #   [21, 2.43290200817664e+18, 2432902008176640000]
 #   [22, 5.109094217170944e+19, 51090942171709440000]
 #   [23, 1.1240007277776077e+21, 1124000727777607680000]
 #   [24, 2.5852016738885062e+22, 25852016738884976640000]
 #   [25, 6.204484017332391e+23, 620448401733239439360000]
 #   [26, 1.5511210043330954e+25, 15511210043330985984000000]

Returns:



793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
# File 'math.c', line 793

static VALUE
math_gamma(VALUE obj, VALUE x)
{
    static const double fact_table[] = {
        /* fact(0) */ 1.0,
        /* fact(1) */ 1.0,
        /* fact(2) */ 2.0,
        /* fact(3) */ 6.0,
        /* fact(4) */ 24.0,
        /* fact(5) */ 120.0,
        /* fact(6) */ 720.0,
        /* fact(7) */ 5040.0,
        /* fact(8) */ 40320.0,
        /* fact(9) */ 362880.0,
        /* fact(10) */ 3628800.0,
        /* fact(11) */ 39916800.0,
        /* fact(12) */ 479001600.0,
        /* fact(13) */ 6227020800.0,
        /* fact(14) */ 87178291200.0,
        /* fact(15) */ 1307674368000.0,
        /* fact(16) */ 20922789888000.0,
        /* fact(17) */ 355687428096000.0,
        /* fact(18) */ 6402373705728000.0,
        /* fact(19) */ 121645100408832000.0,
        /* fact(20) */ 2432902008176640000.0,
        /* fact(21) */ 51090942171709440000.0,
        /* fact(22) */ 1124000727777607680000.0,
        /* fact(23)=25852016738884976640000 needs 56bit mantissa which is
         * impossible to represent exactly in IEEE 754 double which have
         * 53bit mantissa. */
    };
    double d0, d;
    double intpart, fracpart;
    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (isinf(d0) && signbit(d0)) domain_error("gamma");
    fracpart = modf(d0, &intpart);
    if (fracpart == 0.0) {
	if (intpart < 0) domain_error("gamma");
	if (0 < intpart &&
	    intpart - 1 < (double)numberof(fact_table)) {
	    return DBL2NUM(fact_table[(int)intpart - 1]);
	}
    }
    d = tgamma(d0);
    return DBL2NUM(d);
}

.hypot(x, y) ⇒ Float

Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle with sides x and y.

Math.hypot(3, 4)   #=> 5.0

Returns:



704
705
706
707
708
709
# File 'math.c', line 704

static VALUE
math_hypot(VALUE obj, VALUE x, VALUE y)
{
    Need_Float2(x, y);
    return DBL2NUM(hypot(RFLOAT_VALUE(x), RFLOAT_VALUE(y)));
}

.ldexp(fraction, exponent) ⇒ Float

Returns the value of fraction*(2**exponent).

fraction, exponent = Math.frexp(1234)
Math.ldexp(fraction, exponent)   #=> 1234.0

Returns:



687
688
689
690
691
692
# File 'math.c', line 687

static VALUE
math_ldexp(VALUE obj, VALUE x, VALUE n)
{
    Need_Float(x);
    return DBL2NUM(ldexp(RFLOAT_VALUE(x), NUM2INT(n)));
}

.lgamma(x) ⇒ Array, ...

Calculates the logarithmic gamma of x and the sign of gamma of x.

Math.lgamma(x) is same as
 [Math.log(Math.gamma(x).abs), Math.gamma(x) < 0 ? -1 : 1]
but avoid overflow by Math.gamma(x) for large x.

  Math.lgamma(0) #=> [Infinity, 1]

Returns ].

Returns:



856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
# File 'math.c', line 856

static VALUE
math_lgamma(VALUE obj, VALUE x)
{
    double d0, d;
    int sign=1;
    VALUE v;
    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (isinf(d0)) {
	if (signbit(d0)) domain_error("lgamma");
	return rb_assoc_new(DBL2NUM(INFINITY), INT2FIX(1));
    }
    d = lgamma_r(d0, &sign);
    v = DBL2NUM(d);
    return rb_assoc_new(v, INT2FIX(sign));
}

.log(x) ⇒ Float .log(x, base) ⇒ Float

Returns the logarithm of x. If additional second argument is given, it will be the base of logarithm. Otherwise it is e (for the natural logarithm).

Domain: (0, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.log(0)          #=> -Infinity
Math.log(1)          #=> 0.0
Math.log(Math::E)    #=> 1.0
Math.log(Math::E**3) #=> 3.0
Math.log(12, 3)      #=> 2.2618595071429146

Overloads:



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
# File 'math.c', line 440

static VALUE
math_log(int argc, VALUE *argv)
{
    VALUE x, base;
    double d0, d;
    size_t numbits;

    rb_scan_args(argc, argv, "11", &x, &base);

    if (RB_BIGNUM_TYPE_P(x) && RBIGNUM_POSITIVE_P(x) &&
            DBL_MAX_EXP <= (numbits = rb_absint_numwords(x, 1, NULL))) {
        numbits -= DBL_MANT_DIG;
        x = rb_big_rshift(x, SIZET2NUM(numbits));
    }
    else {
	numbits = 0;
    }

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("log");
    /* check for pole error */
    if (d0 == 0.0) return DBL2NUM(-INFINITY);
    d = log(d0);
    if (numbits)
        d += numbits * log(2); /* log(2**numbits) */
    if (argc == 2) {
	Need_Float(base);
	d /= log(RFLOAT_VALUE(base));
    }
    return DBL2NUM(d);
}

.log10(x) ⇒ Float

Returns the base 10 logarithm of x.

Domain: (0, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.log10(1)       #=> 0.0
Math.log10(10)      #=> 1.0
Math.log10(10**100) #=> 100.0

Returns:



545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'math.c', line 545

static VALUE
math_log10(VALUE obj, VALUE x)
{
    double d0, d;
    size_t numbits;

    if (RB_BIGNUM_TYPE_P(x) && RBIGNUM_POSITIVE_P(x) &&
            DBL_MAX_EXP <= (numbits = rb_absint_numwords(x, 1, NULL))) {
        numbits -= DBL_MANT_DIG;
        x = rb_big_rshift(x, SIZET2NUM(numbits));
    }
    else {
	numbits = 0;
    }

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("log10");
    /* check for pole error */
    if (d0 == 0.0) return DBL2NUM(-INFINITY);
    d = log10(d0);
    if (numbits)
        d += numbits * log10(2); /* log10(2**numbits) */
    return DBL2NUM(d);
}

.log2(x) ⇒ Float

Returns the base 2 logarithm of x.

Domain: (0, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.log2(1)      #=> 0.0
Math.log2(2)      #=> 1.0
Math.log2(32768)  #=> 15.0
Math.log2(65536)  #=> 16.0

Returns:



503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
# File 'math.c', line 503

static VALUE
math_log2(VALUE obj, VALUE x)
{
    double d0, d;
    size_t numbits;

    if (RB_BIGNUM_TYPE_P(x) && RBIGNUM_POSITIVE_P(x) &&
            DBL_MAX_EXP <= (numbits = rb_absint_numwords(x, 1, NULL))) {
        numbits -= DBL_MANT_DIG;
        x = rb_big_rshift(x, SIZET2NUM(numbits));
    }
    else {
	numbits = 0;
    }

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("log2");
    /* check for pole error */
    if (d0 == 0.0) return DBL2NUM(-INFINITY);
    d = log2(d0);
    d += numbits;
    return DBL2NUM(d);
}

.sin(x) ⇒ Float

Computes the sine of x (expressed in radians). Returns a Float in the range -1.0..1.0.

Domain: (-INFINITY, INFINITY)

Codomain: [-1, 1]

Math.sin(Math::PI/2) #=> 1.0

Returns:



120
121
122
123
124
125
# File 'math.c', line 120

static VALUE
math_sin(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(sin(RFLOAT_VALUE(x)));
}

.sinh(x) ⇒ Float

Computes the hyperbolic sine of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.sinh(0) #=> 0.0

Returns:



273
274
275
276
277
278
# File 'math.c', line 273

static VALUE
math_sinh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(sinh(RFLOAT_VALUE(x)));
}

.sqrt(x) ⇒ Float

Returns the non-negative square root of x.

Domain: [0, INFINITY)

Codomain:[0, INFINITY)

0.upto(10) {|x|
  p [x, Math.sqrt(x), Math.sqrt(x)**2]
}
#=> [0, 0.0, 0.0]
#   [1, 1.0, 1.0]
#   [2, 1.4142135623731, 2.0]
#   [3, 1.73205080756888, 3.0]
#   [4, 2.0, 4.0]
#   [5, 2.23606797749979, 5.0]
#   [6, 2.44948974278318, 6.0]
#   [7, 2.64575131106459, 7.0]
#   [8, 2.82842712474619, 8.0]
#   [9, 3.0, 9.0]
#   [10, 3.16227766016838, 10.0]

Returns:



598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'math.c', line 598

static VALUE
math_sqrt(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("sqrt");
    if (d0 == 0.0) return DBL2NUM(0.0);
    d = sqrt(d0);
    return DBL2NUM(d);
}

.tan(x) ⇒ Float

Computes the tangent of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.tan(0) #=> 0.0

Returns:



142
143
144
145
146
147
# File 'math.c', line 142

static VALUE
math_tan(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(tan(RFLOAT_VALUE(x)));
}

.tanh(x) ⇒ Float

Computes the hyperbolic tangent of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: (-1, 1)

Math.tanh(0) #=> 0.0

Returns:



302
303
304
305
306
307
# File 'math.c', line 302

static VALUE
math_tanh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(tanh(RFLOAT_VALUE(x)));
}

Instance Method Details

#acos(x) ⇒ Float (private)

Computes the arc cosine of x. Returns 0..PI.

Domain: [-1, 1]

Codomain: [0, PI]

Math.acos(0) == Math::PI/2  #=> true

Returns:



163
164
165
166
167
168
169
170
171
172
173
174
# File 'math.c', line 163

static VALUE
math_acos(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < -1.0 || 1.0 < d0) domain_error("acos");
    d = acos(d0);
    return DBL2NUM(d);
}

#acosh(x) ⇒ Float (private)

Computes the inverse hyperbolic cosine of x.

Domain: [1, INFINITY)

Codomain: [0, INFINITY)

Math.acosh(1) #=> 0.0

Returns:



323
324
325
326
327
328
329
330
331
332
333
334
# File 'math.c', line 323

static VALUE
math_acosh(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 1.0) domain_error("acosh");
    d = acosh(d0);
    return DBL2NUM(d);
}

#asin(x) ⇒ Float (private)

Computes the arc sine of x. Returns -PI/2..PI/2.

Domain: [-1, -1]

Codomain: [-PI/2, PI/2]

Math.asin(1) == Math::PI/2  #=> true

Returns:



189
190
191
192
193
194
195
196
197
198
199
200
# File 'math.c', line 189

static VALUE
math_asin(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < -1.0 || 1.0 < d0) domain_error("asin");
    d = asin(d0);
    return DBL2NUM(d);
}

#asinh(x) ⇒ Float (private)

Computes the inverse hyperbolic sine of x.

Domain: (-INFINITY, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.asinh(1) #=> 0.881373587019543

Returns:



350
351
352
353
354
355
# File 'math.c', line 350

static VALUE
math_asinh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(asinh(RFLOAT_VALUE(x)));
}

#atan(x) ⇒ Float (private)

Computes the arc tangent of x. Returns -PI/2..PI/2.

Domain: (-INFINITY, INFINITY)

Codomain: (-PI/2, PI/2)

Math.atan(0) #=> 0.0

Returns:



215
216
217
218
219
220
# File 'math.c', line 215

static VALUE
math_atan(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(atan(RFLOAT_VALUE(x)));
}

#atan2(y, x) ⇒ Float (private)

Computes the arc tangent given y and x. Returns a Float in the range -PI..PI.

Domain: (-INFINITY, INFINITY)

Codomain: [-PI, PI]

Math.atan2(-0.0, -1.0) #=> -3.141592653589793
Math.atan2(-1.0, -1.0) #=> -2.356194490192345
Math.atan2(-1.0, 0.0)  #=> -1.5707963267948966
Math.atan2(-1.0, 1.0)  #=> -0.7853981633974483
Math.atan2(-0.0, 1.0)  #=> -0.0
Math.atan2(0.0, 1.0)   #=> 0.0
Math.atan2(1.0, 1.0)   #=> 0.7853981633974483
Math.atan2(1.0, 0.0)   #=> 1.5707963267948966
Math.atan2(1.0, -1.0)  #=> 2.356194490192345
Math.atan2(0.0, -1.0)  #=> 3.141592653589793

Returns:



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'math.c', line 61

static VALUE
math_atan2(VALUE obj, VALUE y, VALUE x)
{
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
    double dx, dy;
    Need_Float2(y, x);
    dx = RFLOAT_VALUE(x);
    dy = RFLOAT_VALUE(y);
    if (dx == 0.0 && dy == 0.0) {
	if (!signbit(dx))
	    return DBL2NUM(dy);
        if (!signbit(dy))
	    return DBL2NUM(M_PI);
	return DBL2NUM(-M_PI);
    }
    if (isinf(dx) && isinf(dy)) domain_error("atan2");
    return DBL2NUM(atan2(dy, dx));
}

#atanh(x) ⇒ Float (private)

Computes the inverse hyperbolic tangent of x.

Domain: (-1, 1)

Codomain: (-INFINITY, INFINITY)

Math.atanh(1) #=> Infinity

Returns:



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'math.c', line 371

static VALUE
math_atanh(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 <  -1.0 || +1.0 <  d0) domain_error("atanh");
    /* check for pole error */
    if (d0 == -1.0) return DBL2NUM(-INFINITY);
    if (d0 == +1.0) return DBL2NUM(+INFINITY);
    d = atanh(d0);
    return DBL2NUM(d);
}

#cbrt(x) ⇒ Float (private)

Returns the cube root of x.

Domain: [0, INFINITY)

Codomain:[0, INFINITY)

-9.upto(9) {|x|
  p [x, Math.cbrt(x), Math.cbrt(x)**3]
}
#=> [-9, -2.0800838230519, -9.0]
#   [-8, -2.0, -8.0]
#   [-7, -1.91293118277239, -7.0]
#   [-6, -1.81712059283214, -6.0]
#   [-5, -1.7099759466767, -5.0]
#   [-4, -1.5874010519682, -4.0]
#   [-3, -1.44224957030741, -3.0]
#   [-2, -1.25992104989487, -2.0]
#   [-1, -1.0, -1.0]
#   [0, 0.0, 0.0]
#   [1, 1.0, 1.0]
#   [2, 1.25992104989487, 2.0]
#   [3, 1.44224957030741, 3.0]
#   [4, 1.5874010519682, 4.0]
#   [5, 1.7099759466767, 5.0]
#   [6, 1.81712059283214, 6.0]
#   [7, 1.91293118277239, 7.0]
#   [8, 2.0, 8.0]
#   [9, 2.0800838230519, 9.0]

Returns:



647
648
649
650
651
652
# File 'math.c', line 647

static VALUE
math_cbrt(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(cbrt(RFLOAT_VALUE(x)));
}

#cos(x) ⇒ Float (private)

Computes the cosine of x (expressed in radians). Returns a Float in the range -1.0..1.0.

Domain: (-INFINITY, INFINITY)

Codomain: [-1, 1]

Math.cos(Math::PI) #=> -1.0

Returns:



98
99
100
101
102
103
# File 'math.c', line 98

static VALUE
math_cos(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(cos(RFLOAT_VALUE(x)));
}

#cosh(x) ⇒ Float (private)

Computes the hyperbolic cosine of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: [1, INFINITY)

Math.cosh(0) #=> 1.0

Returns:



244
245
246
247
248
249
# File 'math.c', line 244

static VALUE
math_cosh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(cosh(RFLOAT_VALUE(x)));
}

#erf(x) ⇒ Float (private)

Calculates the error function of x.

Domain: (-INFINITY, INFINITY)

Codomain: (-1, 1)

  Math.erf(0) #=> 0.0

Returns:



725
726
727
728
729
730
# File 'math.c', line 725

static VALUE
math_erf(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(erf(RFLOAT_VALUE(x)));
}

#erfc(x) ⇒ Float (private)

Calculates the complementary error function of x.

Domain: (-INFINITY, INFINITY)

Codomain: (0, 2)

  Math.erfc(0) #=> 1.0

Returns:



746
747
748
749
750
751
# File 'math.c', line 746

static VALUE
math_erfc(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(erfc(RFLOAT_VALUE(x)));
}

#exp(x) ⇒ Float (private)

Returns e**x.

Domain: (-INFINITY, INFINITY)

Codomain: (0, INFINITY)

Math.exp(0)       #=> 1.0
Math.exp(1)       #=> 2.718281828459045
Math.exp(1.5)     #=> 4.4816890703380645

Returns:



403
404
405
406
407
408
# File 'math.c', line 403

static VALUE
math_exp(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(exp(RFLOAT_VALUE(x)));
}

#frexp(x) ⇒ Array (private)

Returns a two-element array containing the normalized fraction (a Float) and exponent (a Fixnum) of x.

fraction, exponent = Math.frexp(1234)   #=> [0.6025390625, 11]
fraction * 2**exponent                  #=> 1234.0

Returns:



665
666
667
668
669
670
671
672
673
674
675
# File 'math.c', line 665

static VALUE
math_frexp(VALUE obj, VALUE x)
{
    double d;
    int exp;

    Need_Float(x);

    d = frexp(RFLOAT_VALUE(x), &exp);
    return rb_assoc_new(DBL2NUM(d), INT2NUM(exp));
}

#gamma(x) ⇒ Float (private)

Calculates the gamma function of x.

Note that gamma(n) is same as fact(n-1) for integer n > 0.
However gamma(n) returns float and can be an approximation.

 def fact(n) (1..n).inject(1) {|r,i| r*i } end
 1.upto(26) {|i| p [i, Math.gamma(i), fact(i-1)] }
 #=> [1, 1.0, 1]
 #   [2, 1.0, 1]
 #   [3, 2.0, 2]
 #   [4, 6.0, 6]
 #   [5, 24.0, 24]
 #   [6, 120.0, 120]
 #   [7, 720.0, 720]
 #   [8, 5040.0, 5040]
 #   [9, 40320.0, 40320]
 #   [10, 362880.0, 362880]
 #   [11, 3628800.0, 3628800]
 #   [12, 39916800.0, 39916800]
 #   [13, 479001600.0, 479001600]
 #   [14, 6227020800.0, 6227020800]
 #   [15, 87178291200.0, 87178291200]
 #   [16, 1307674368000.0, 1307674368000]
 #   [17, 20922789888000.0, 20922789888000]
 #   [18, 355687428096000.0, 355687428096000]
 #   [19, 6.402373705728e+15, 6402373705728000]
 #   [20, 1.21645100408832e+17, 121645100408832000]
 #   [21, 2.43290200817664e+18, 2432902008176640000]
 #   [22, 5.109094217170944e+19, 51090942171709440000]
 #   [23, 1.1240007277776077e+21, 1124000727777607680000]
 #   [24, 2.5852016738885062e+22, 25852016738884976640000]
 #   [25, 6.204484017332391e+23, 620448401733239439360000]
 #   [26, 1.5511210043330954e+25, 15511210043330985984000000]

Returns:



793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
# File 'math.c', line 793

static VALUE
math_gamma(VALUE obj, VALUE x)
{
    static const double fact_table[] = {
        /* fact(0) */ 1.0,
        /* fact(1) */ 1.0,
        /* fact(2) */ 2.0,
        /* fact(3) */ 6.0,
        /* fact(4) */ 24.0,
        /* fact(5) */ 120.0,
        /* fact(6) */ 720.0,
        /* fact(7) */ 5040.0,
        /* fact(8) */ 40320.0,
        /* fact(9) */ 362880.0,
        /* fact(10) */ 3628800.0,
        /* fact(11) */ 39916800.0,
        /* fact(12) */ 479001600.0,
        /* fact(13) */ 6227020800.0,
        /* fact(14) */ 87178291200.0,
        /* fact(15) */ 1307674368000.0,
        /* fact(16) */ 20922789888000.0,
        /* fact(17) */ 355687428096000.0,
        /* fact(18) */ 6402373705728000.0,
        /* fact(19) */ 121645100408832000.0,
        /* fact(20) */ 2432902008176640000.0,
        /* fact(21) */ 51090942171709440000.0,
        /* fact(22) */ 1124000727777607680000.0,
        /* fact(23)=25852016738884976640000 needs 56bit mantissa which is
         * impossible to represent exactly in IEEE 754 double which have
         * 53bit mantissa. */
    };
    double d0, d;
    double intpart, fracpart;
    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (isinf(d0) && signbit(d0)) domain_error("gamma");
    fracpart = modf(d0, &intpart);
    if (fracpart == 0.0) {
	if (intpart < 0) domain_error("gamma");
	if (0 < intpart &&
	    intpart - 1 < (double)numberof(fact_table)) {
	    return DBL2NUM(fact_table[(int)intpart - 1]);
	}
    }
    d = tgamma(d0);
    return DBL2NUM(d);
}

#hypot(x, y) ⇒ Float (private)

Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle with sides x and y.

Math.hypot(3, 4)   #=> 5.0

Returns:



704
705
706
707
708
709
# File 'math.c', line 704

static VALUE
math_hypot(VALUE obj, VALUE x, VALUE y)
{
    Need_Float2(x, y);
    return DBL2NUM(hypot(RFLOAT_VALUE(x), RFLOAT_VALUE(y)));
}

#ldexp(fraction, exponent) ⇒ Float (private)

Returns the value of fraction*(2**exponent).

fraction, exponent = Math.frexp(1234)
Math.ldexp(fraction, exponent)   #=> 1234.0

Returns:



687
688
689
690
691
692
# File 'math.c', line 687

static VALUE
math_ldexp(VALUE obj, VALUE x, VALUE n)
{
    Need_Float(x);
    return DBL2NUM(ldexp(RFLOAT_VALUE(x), NUM2INT(n)));
}

#lgamma(x) ⇒ Array, ... (private)

Calculates the logarithmic gamma of x and the sign of gamma of x.

Math.lgamma(x) is same as
 [Math.log(Math.gamma(x).abs), Math.gamma(x) < 0 ? -1 : 1]
but avoid overflow by Math.gamma(x) for large x.

  Math.lgamma(0) #=> [Infinity, 1]

Returns ].

Returns:



856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
# File 'math.c', line 856

static VALUE
math_lgamma(VALUE obj, VALUE x)
{
    double d0, d;
    int sign=1;
    VALUE v;
    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (isinf(d0)) {
	if (signbit(d0)) domain_error("lgamma");
	return rb_assoc_new(DBL2NUM(INFINITY), INT2FIX(1));
    }
    d = lgamma_r(d0, &sign);
    v = DBL2NUM(d);
    return rb_assoc_new(v, INT2FIX(sign));
}

#log(x) ⇒ Float (private) #log(x, base) ⇒ Float (private)

Returns the logarithm of x. If additional second argument is given, it will be the base of logarithm. Otherwise it is e (for the natural logarithm).

Domain: (0, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.log(0)          #=> -Infinity
Math.log(1)          #=> 0.0
Math.log(Math::E)    #=> 1.0
Math.log(Math::E**3) #=> 3.0
Math.log(12, 3)      #=> 2.2618595071429146

Overloads:



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
# File 'math.c', line 440

static VALUE
math_log(int argc, VALUE *argv)
{
    VALUE x, base;
    double d0, d;
    size_t numbits;

    rb_scan_args(argc, argv, "11", &x, &base);

    if (RB_BIGNUM_TYPE_P(x) && RBIGNUM_POSITIVE_P(x) &&
            DBL_MAX_EXP <= (numbits = rb_absint_numwords(x, 1, NULL))) {
        numbits -= DBL_MANT_DIG;
        x = rb_big_rshift(x, SIZET2NUM(numbits));
    }
    else {
	numbits = 0;
    }

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("log");
    /* check for pole error */
    if (d0 == 0.0) return DBL2NUM(-INFINITY);
    d = log(d0);
    if (numbits)
        d += numbits * log(2); /* log(2**numbits) */
    if (argc == 2) {
	Need_Float(base);
	d /= log(RFLOAT_VALUE(base));
    }
    return DBL2NUM(d);
}

#log10(x) ⇒ Float (private)

Returns the base 10 logarithm of x.

Domain: (0, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.log10(1)       #=> 0.0
Math.log10(10)      #=> 1.0
Math.log10(10**100) #=> 100.0

Returns:



545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'math.c', line 545

static VALUE
math_log10(VALUE obj, VALUE x)
{
    double d0, d;
    size_t numbits;

    if (RB_BIGNUM_TYPE_P(x) && RBIGNUM_POSITIVE_P(x) &&
            DBL_MAX_EXP <= (numbits = rb_absint_numwords(x, 1, NULL))) {
        numbits -= DBL_MANT_DIG;
        x = rb_big_rshift(x, SIZET2NUM(numbits));
    }
    else {
	numbits = 0;
    }

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("log10");
    /* check for pole error */
    if (d0 == 0.0) return DBL2NUM(-INFINITY);
    d = log10(d0);
    if (numbits)
        d += numbits * log10(2); /* log10(2**numbits) */
    return DBL2NUM(d);
}

#log2(x) ⇒ Float (private)

Returns the base 2 logarithm of x.

Domain: (0, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.log2(1)      #=> 0.0
Math.log2(2)      #=> 1.0
Math.log2(32768)  #=> 15.0
Math.log2(65536)  #=> 16.0

Returns:



503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
# File 'math.c', line 503

static VALUE
math_log2(VALUE obj, VALUE x)
{
    double d0, d;
    size_t numbits;

    if (RB_BIGNUM_TYPE_P(x) && RBIGNUM_POSITIVE_P(x) &&
            DBL_MAX_EXP <= (numbits = rb_absint_numwords(x, 1, NULL))) {
        numbits -= DBL_MANT_DIG;
        x = rb_big_rshift(x, SIZET2NUM(numbits));
    }
    else {
	numbits = 0;
    }

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("log2");
    /* check for pole error */
    if (d0 == 0.0) return DBL2NUM(-INFINITY);
    d = log2(d0);
    d += numbits;
    return DBL2NUM(d);
}

#sin(x) ⇒ Float (private)

Computes the sine of x (expressed in radians). Returns a Float in the range -1.0..1.0.

Domain: (-INFINITY, INFINITY)

Codomain: [-1, 1]

Math.sin(Math::PI/2) #=> 1.0

Returns:



120
121
122
123
124
125
# File 'math.c', line 120

static VALUE
math_sin(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(sin(RFLOAT_VALUE(x)));
}

#sinh(x) ⇒ Float (private)

Computes the hyperbolic sine of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.sinh(0) #=> 0.0

Returns:



273
274
275
276
277
278
# File 'math.c', line 273

static VALUE
math_sinh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(sinh(RFLOAT_VALUE(x)));
}

#sqrt(x) ⇒ Float (private)

Returns the non-negative square root of x.

Domain: [0, INFINITY)

Codomain:[0, INFINITY)

0.upto(10) {|x|
  p [x, Math.sqrt(x), Math.sqrt(x)**2]
}
#=> [0, 0.0, 0.0]
#   [1, 1.0, 1.0]
#   [2, 1.4142135623731, 2.0]
#   [3, 1.73205080756888, 3.0]
#   [4, 2.0, 4.0]
#   [5, 2.23606797749979, 5.0]
#   [6, 2.44948974278318, 6.0]
#   [7, 2.64575131106459, 7.0]
#   [8, 2.82842712474619, 8.0]
#   [9, 3.0, 9.0]
#   [10, 3.16227766016838, 10.0]

Returns:



598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'math.c', line 598

static VALUE
math_sqrt(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    /* check for domain error */
    if (d0 < 0.0) domain_error("sqrt");
    if (d0 == 0.0) return DBL2NUM(0.0);
    d = sqrt(d0);
    return DBL2NUM(d);
}

#tan(x) ⇒ Float (private)

Computes the tangent of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: (-INFINITY, INFINITY)

Math.tan(0) #=> 0.0

Returns:



142
143
144
145
146
147
# File 'math.c', line 142

static VALUE
math_tan(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(tan(RFLOAT_VALUE(x)));
}

#tanh(x) ⇒ Float (private)

Computes the hyperbolic tangent of x (expressed in radians).

Domain: (-INFINITY, INFINITY)

Codomain: (-1, 1)

Math.tanh(0) #=> 0.0

Returns:



302
303
304
305
306
307
# File 'math.c', line 302

static VALUE
math_tanh(VALUE obj, VALUE x)
{
    Need_Float(x);
    return DBL2NUM(tanh(RFLOAT_VALUE(x)));
}