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:


178
179
180
181
182
183
184
185
186
187
188
189
# File 'math.c', line 178

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:


338
339
340
341
342
343
344
345
346
347
348
349
# File 'math.c', line 338

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:


204
205
206
207
208
209
210
211
212
213
214
215
# File 'math.c', line 204

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:


365
366
367
368
369
370
# File 'math.c', line 365

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:


230
231
232
233
234
235
# File 'math.c', line 230

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
Math.atan2(INFINITY, INFINITY)   #=> 0.7853981633974483
Math.atan2(INFINITY, -INFINITY)  #=> 2.356194490192345
Math.atan2(-INFINITY, INFINITY)  #=> -0.7853981633974483
Math.atan2(-INFINITY, -INFINITY) #=> -2.356194490192345

Returns:


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'math.c', line 64

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);
    }
#ifndef ATAN2_INF_C99
    if (isinf(dx) && isinf(dy)) {
	/* optimization for FLONUM */
	if (dx < 0.0) {
	    const double dz = (3.0 * M_PI / 4.0);
	    return (dy < 0.0) ? DBL2NUM(-dz) : DBL2NUM(dz);
	}
	else {
	    const double dz = (M_PI / 4.0);
	    return (dy < 0.0) ? DBL2NUM(-dz) : DBL2NUM(dz);
	}
    }
#endif
    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:


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'math.c', line 386

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:


671
672
673
674
675
676
# File 'math.c', line 671

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:


113
114
115
116
117
118
# File 'math.c', line 113

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:


259
260
261
262
263
264
# File 'math.c', line 259

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:


749
750
751
752
753
754
# File 'math.c', line 749

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:


770
771
772
773
774
775
# File 'math.c', line 770

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:


418
419
420
421
422
423
# File 'math.c', line 418

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:


689
690
691
692
693
694
695
696
697
698
699
# File 'math.c', line 689

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:


817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
# File 'math.c', line 817

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:


728
729
730
731
732
733
# File 'math.c', line 728

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:


711
712
713
714
715
716
# File 'math.c', line 711

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:


880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
# File 'math.c', line 880

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:


457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'math.c', line 457

static VALUE
math_log(int argc, const VALUE *argv, VALUE obj)
{
    VALUE x, base;
    double d;

    rb_scan_args(argc, argv, "11", &x, &base);
    d = math_log1(x);
    if (argc == 2) {
	d /= math_log1(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:


569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
# File 'math.c', line 569

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

    if (RB_BIGNUM_TYPE_P(x) && BIGNUM_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:


527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# File 'math.c', line 527

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

    if (RB_BIGNUM_TYPE_P(x) && BIGNUM_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:


135
136
137
138
139
140
# File 'math.c', line 135

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:


288
289
290
291
292
293
# File 'math.c', line 288

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:


622
623
624
625
626
627
628
629
630
631
632
633
634
# File 'math.c', line 622

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:


157
158
159
160
161
162
# File 'math.c', line 157

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:


317
318
319
320
321
322
# File 'math.c', line 317

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:


178
179
180
181
182
183
184
185
186
187
188
189
# File 'math.c', line 178

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:


338
339
340
341
342
343
344
345
346
347
348
349
# File 'math.c', line 338

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:


204
205
206
207
208
209
210
211
212
213
214
215
# File 'math.c', line 204

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:


365
366
367
368
369
370
# File 'math.c', line 365

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:


230
231
232
233
234
235
# File 'math.c', line 230

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
Math.atan2(INFINITY, INFINITY)   #=> 0.7853981633974483
Math.atan2(INFINITY, -INFINITY)  #=> 2.356194490192345
Math.atan2(-INFINITY, INFINITY)  #=> -0.7853981633974483
Math.atan2(-INFINITY, -INFINITY) #=> -2.356194490192345

Returns:


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'math.c', line 64

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);
    }
#ifndef ATAN2_INF_C99
    if (isinf(dx) && isinf(dy)) {
	/* optimization for FLONUM */
	if (dx < 0.0) {
	    const double dz = (3.0 * M_PI / 4.0);
	    return (dy < 0.0) ? DBL2NUM(-dz) : DBL2NUM(dz);
	}
	else {
	    const double dz = (M_PI / 4.0);
	    return (dy < 0.0) ? DBL2NUM(-dz) : DBL2NUM(dz);
	}
    }
#endif
    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:


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'math.c', line 386

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:


671
672
673
674
675
676
# File 'math.c', line 671

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:


113
114
115
116
117
118
# File 'math.c', line 113

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:


259
260
261
262
263
264
# File 'math.c', line 259

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:


749
750
751
752
753
754
# File 'math.c', line 749

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:


770
771
772
773
774
775
# File 'math.c', line 770

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:


418
419
420
421
422
423
# File 'math.c', line 418

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:


689
690
691
692
693
694
695
696
697
698
699
# File 'math.c', line 689

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:


817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
# File 'math.c', line 817

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:


728
729
730
731
732
733
# File 'math.c', line 728

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:


711
712
713
714
715
716
# File 'math.c', line 711

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:


880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
# File 'math.c', line 880

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:


457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'math.c', line 457

static VALUE
math_log(int argc, const VALUE *argv, VALUE obj)
{
    VALUE x, base;
    double d;

    rb_scan_args(argc, argv, "11", &x, &base);
    d = math_log1(x);
    if (argc == 2) {
	d /= math_log1(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:


569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
# File 'math.c', line 569

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

    if (RB_BIGNUM_TYPE_P(x) && BIGNUM_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:


527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# File 'math.c', line 527

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

    if (RB_BIGNUM_TYPE_P(x) && BIGNUM_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:


135
136
137
138
139
140
# File 'math.c', line 135

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:


288
289
290
291
292
293
# File 'math.c', line 288

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:


622
623
624
625
626
627
628
629
630
631
632
633
634
# File 'math.c', line 622

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:


157
158
159
160
161
162
# File 'math.c', line 157

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:


317
318
319
320
321
322
# File 'math.c', line 317

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