Module Math
In: math.c
lib/complex.rb
lib/mathn.rb

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.

Methods

acos   acos   acosh   acosh   asin   asin   asinh   asinh   atan   atan   atan2   atan2   atanh   atanh   cos   cos   cosh   cosh   erf   erfc   exp   exp   frexp   hypot   ldexp   log   log   log10   log10   rsqrt   sin   sin   sinh   sinh   sqrt   sqrt   sqrt   tan   tan   tanh   tanh  

Constants

PI = rb_float_new(M_PI)
PI = rb_float_new(atan(1.0)*4.0)
E = rb_float_new(M_E)
E = rb_float_new(exp(1.0))

External Aliases

sqrt -> sqrt!
exp -> exp!
log -> log!
log10 -> log10!
cos -> cos!
sin -> sin!
tan -> tan!
cosh -> cosh!
sinh -> sinh!
tanh -> tanh!
acos -> acos!
asin -> asin!
atan -> atan!
atan2 -> atan2!
acosh -> acosh!
asinh -> asinh!
atanh -> atanh!

Public Class methods

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

[Source]

/*
 *  call-seq:
 *     Math.acos(x)    => float
 *  
 *  Computes the arc cosine of <i>x</i>. Returns 0..PI.
 */

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

    Need_Float(x);
    errno = 0;
    d = acos(RFLOAT(x)->value);
    domain_check(d, "acos");
    return rb_float_new(d);
}

Computes the inverse hyperbolic cosine of x.

[Source]

/*
 *  call-seq:
 *     Math.acosh(x)    => float
 *  
 *  Computes the inverse hyperbolic cosine of <i>x</i>.
 */

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

    Need_Float(x);
    errno = 0;
    d = acosh(RFLOAT(x)->value);
    domain_check(d, "acosh");
    return rb_float_new(d);
}

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

[Source]

/*
 *  call-seq:
 *     Math.asin(x)    => float
 *  
 *  Computes the arc sine of <i>x</i>. Returns -{PI/2} .. {PI/2}.
 */

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

    Need_Float(x);
    errno = 0;
    d = asin(RFLOAT(x)->value);
    domain_check(d, "asin");
    return rb_float_new(d);
}

Computes the inverse hyperbolic sine of x.

[Source]

/*
 *  call-seq:
 *     Math.asinh(x)    => float
 *  
 *  Computes the inverse hyperbolic sine of <i>x</i>.
 */

static VALUE
math_asinh(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(asinh(RFLOAT(x)->value));
}

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

[Source]

/*
 *  call-seq:
 *     Math.atan(x)    => float
 *  
 *  Computes the arc tangent of <i>x</i>. Returns -{PI/2} .. {PI/2}.
 */

static VALUE
math_atan(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(atan(RFLOAT(x)->value));
}

Computes the arc tangent given y and x. Returns -PI..PI.

[Source]

/*
 *  call-seq:
 *     Math.atan2(y, x)  => float
 *  
 *  Computes the arc tangent given <i>y</i> and <i>x</i>. Returns
 *  -PI..PI.
 *     
 */

static VALUE
math_atan2(obj, y, x)
    VALUE obj, x, y;
{
    Need_Float2(y, x);
    return rb_float_new(atan2(RFLOAT(y)->value, RFLOAT(x)->value));
}

Computes the inverse hyperbolic tangent of x.

[Source]

/*
 *  call-seq:
 *     Math.atanh(x)    => float
 *  
 *  Computes the inverse hyperbolic tangent of <i>x</i>.
 */

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

    Need_Float(x);
    errno = 0;
    d = atanh(RFLOAT(x)->value);
    domain_check(d, "atanh");
    return rb_float_new(d);
}

Computes the cosine of x (expressed in radians). Returns -1..1.

[Source]

/*
 *  call-seq:
 *     Math.cos(x)    => float
 *  
 *  Computes the cosine of <i>x</i> (expressed in radians). Returns
 *  -1..1.
 */

static VALUE
math_cos(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(cos(RFLOAT(x)->value));
}

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

[Source]

/*
 *  call-seq:
 *     Math.cosh(x)    => float
 *  
 *  Computes the hyperbolic cosine of <i>x</i> (expressed in radians).
 */

static VALUE
math_cosh(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    
    return rb_float_new(cosh(RFLOAT(x)->value));
}

Calculates the error function of x.

[Source]

/*
 * call-seq:
 *    Math.erf(x)  => float
 *
 *  Calculates the error function of x.
 */

static VALUE
math_erf(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(erf(RFLOAT(x)->value));
}

Calculates the complementary error function of x.

[Source]

/*
 * call-seq:
 *    Math.erfc(x)  => float
 *
 *  Calculates the complementary error function of x.
 */

static VALUE
math_erfc(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(erfc(RFLOAT(x)->value));
}

Returns e**x.

[Source]

/*
 *  call-seq:
 *     Math.exp(x)    => float
 *  
 *  Returns e**x.
 */

static VALUE
math_exp(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(exp(RFLOAT(x)->value));
}

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

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

[Source]

/*
 *  call-seq:
 *     Math.frexp(numeric)    => [ fraction, exponent ]
 *  
 *  Returns a two-element array containing the normalized fraction (a
 *  <code>Float</code>) and exponent (a <code>Fixnum</code>) of
 *  <i>numeric</i>.
 *     
 *     fraction, exponent = Math.frexp(1234)   #=> [0.6025390625, 11]
 *     fraction * 2**exponent                  #=> 1234.0
 */

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

    Need_Float(x);
    
    d = frexp(RFLOAT(x)->value, &exp);
    return rb_assoc_new(rb_float_new(d), INT2NUM(exp));
}

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

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

[Source]

/*
 *  call-seq:
 *     Math.hypot(x, y)    => float
 *  
 *  Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle
 *  with sides <i>x</i> and <i>y</i>.
 *     
 *     Math.hypot(3, 4)   #=> 5.0
 */

static VALUE
math_hypot(obj, x, y)
    VALUE obj, x, y;
{
    Need_Float2(x, y);
    return rb_float_new(hypot(RFLOAT(x)->value, RFLOAT(y)->value));
}

Returns the value of flt*(2**int).

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

[Source]

/*
 *  call-seq:
 *     Math.ldexp(flt, int) -> float
 *  
 *  Returns the value of <i>flt</i>*(2**<i>int</i>).
 *     
 *     fraction, exponent = Math.frexp(1234)
 *     Math.ldexp(fraction, exponent)   #=> 1234.0
 */

static VALUE
math_ldexp(obj, x, n)
    VALUE obj, x, n;
{
    Need_Float(x);
    return rb_float_new(ldexp(RFLOAT(x)->value, NUM2INT(n)));
}

Returns the natural logarithm of numeric.

[Source]

/*
 *  call-seq:
 *     Math.log(numeric)    => float
 *  
 *  Returns the natural logarithm of <i>numeric</i>.
 */

static VALUE
math_log(obj, x)
    VALUE obj, x;
{
    double d;

    Need_Float(x);
    errno = 0;
    d = log(RFLOAT(x)->value);
    domain_check(d, "log");
    return rb_float_new(d);
}

Returns the base 10 logarithm of numeric.

[Source]

/*
 *  call-seq:
 *     Math.log10(numeric)    => float
 *  
 *  Returns the base 10 logarithm of <i>numeric</i>.
 */

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

    Need_Float(x);
    errno = 0;
    d = log10(RFLOAT(x)->value);
    domain_check(d, "log10");
    return rb_float_new(d);
}

Computes the sine of x (expressed in radians). Returns -1..1.

[Source]

/*
 *  call-seq:
 *     Math.sin(x)    => float
 *  
 *  Computes the sine of <i>x</i> (expressed in radians). Returns
 *  -1..1.
 */

static VALUE
math_sin(obj, x)
    VALUE obj, x;
{
    Need_Float(x);

    return rb_float_new(sin(RFLOAT(x)->value));
}

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

[Source]

/*
 *  call-seq:
 *     Math.sinh(x)    => float
 *  
 *  Computes the hyperbolic sine of <i>x</i> (expressed in
 *  radians).
 */

static VALUE
math_sinh(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(sinh(RFLOAT(x)->value));
}

Returns the non-negative square root of numeric.

[Source]

/*
 *  call-seq:
 *     Math.sqrt(numeric)    => float
 *  
 *  Returns the non-negative square root of <i>numeric</i>.
 */

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

    Need_Float(x);
    errno = 0;
    d = sqrt(RFLOAT(x)->value);
    domain_check(d, "sqrt");
    return rb_float_new(d);
}

Returns the tangent of x (expressed in radians).

[Source]

/*
 *  call-seq:
 *     Math.tan(x)    => float
 *  
 *  Returns the tangent of <i>x</i> (expressed in radians).
 */

static VALUE
math_tan(obj, x)
    VALUE obj, x;
{
    Need_Float(x);

    return rb_float_new(tan(RFLOAT(x)->value));
}

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

[Source]

/*
 *  call-seq:
 *     Math.tanh()    => float
 *  
 *  Computes the hyperbolic tangent of <i>x</i> (expressed in
 *  radians).
 */

static VALUE
math_tanh(obj, x)
    VALUE obj, x;
{
    Need_Float(x);
    return rb_float_new(tanh(RFLOAT(x)->value));
}

Public Instance methods

[Source]

     # File lib/complex.rb, line 566
566:   def acos(z)
567:     if Complex.generic?(z) and z >= -1 and z <= 1
568:       acos!(z)
569:     else
570:       -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) )
571:     end
572:   end

[Source]

     # File lib/complex.rb, line 598
598:   def acosh(z)
599:     if Complex.generic?(z) and z >= 1
600:       acosh!(z)
601:     else
602:       log( z + sqrt(z*z-1.0) )
603:     end
604:   end

[Source]

     # File lib/complex.rb, line 574
574:   def asin(z)
575:     if Complex.generic?(z) and z >= -1 and z <= 1
576:       asin!(z)
577:     else
578:       -1.0.im * log( 1.0.im * z + sqrt(1.0-z*z) )
579:     end
580:   end

[Source]

     # File lib/complex.rb, line 606
606:   def asinh(z)
607:     if Complex.generic?(z)
608:       asinh!(z)
609:     else
610:       log( z + sqrt(1.0+z*z) )
611:     end
612:   end

[Source]

     # File lib/complex.rb, line 582
582:   def atan(z)
583:     if Complex.generic?(z)
584:       atan!(z)
585:     else
586:       1.0.im * log( (1.0.im+z) / (1.0.im-z) ) / 2.0
587:     end
588:   end

[Source]

     # File lib/complex.rb, line 590
590:   def atan2(y,x)
591:     if Complex.generic?(y) and Complex.generic?(x)
592:       atan2!(y,x)
593:     else
594:       -1.0.im * log( (x+1.0.im*y) / sqrt(x*x+y*y) )
595:     end
596:   end

[Source]

     # File lib/complex.rb, line 614
614:   def atanh(z)
615:     if Complex.generic?(z) and z >= -1 and z <= 1
616:       atanh!(z)
617:     else
618:       log( (1.0+z) / (1.0-z) ) / 2.0
619:     end
620:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 495
495:   def cos(z)
496:     if Complex.generic?(z)
497:       cos!(z)
498:     else
499:       Complex(cos!(z.real)*cosh!(z.image),
500:               -sin!(z.real)*sinh!(z.image))
501:     end
502:   end

[Source]

     # File lib/complex.rb, line 531
531:   def cosh(z)
532:     if Complex.generic?(z)
533:       cosh!(z)
534:     else
535:       Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) )
536:     end
537:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 486
486:   def exp(z)
487:     if Complex.generic?(z)
488:       exp!(z)
489:     else
490:       Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))
491:     end
492:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 548
548:   def log(z)
549:     if Complex.generic?(z) and z >= 0
550:       log!(z)
551:     else
552:       r, theta = z.polar
553:       Complex(log!(r.abs), theta)
554:     end
555:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 558
558:   def log10(z)
559:     if Complex.generic?(z)
560:       log10!(z)
561:     else
562:       log(z)/log!(10)
563:     end
564:   end

[Source]

     # File lib/mathn.rb, line 256
256:   def rsqrt(a)
257:     if a.kind_of?(Float)
258:       sqrt!(a)
259:     elsif a.kind_of?(Rational)
260:       rsqrt(a.numerator)/rsqrt(a.denominator)
261:     else
262:       src = a
263:       max = 2 ** 32
264:       byte_a = [src & 0xffffffff]
265:       # ruby's bug
266:       while (src >= max) and (src >>= 32)
267:         byte_a.unshift src & 0xffffffff
268:       end
269:       
270:       answer = 0
271:       main = 0
272:       side = 0
273:       for elm in byte_a
274:         main = (main << 32) + elm
275:         side <<= 16
276:         if answer != 0
277:           if main * 4  < side * side
278:             applo = main.div(side)
279:           else 
280:             applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
281:           end
282:         else
283:           applo = sqrt!(main).to_i + 1
284:         end
285:         
286:         while (x = (side + applo) * applo) > main
287:           applo -= 1
288:         end
289:         main -= x
290:         answer = (answer << 16) + applo
291:         side += applo * 2
292:       end
293:       if main == 0
294:         answer
295:       else
296:         sqrt!(a)
297:       end
298:     end
299:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 505
505:   def sin(z)
506:     if Complex.generic?(z)
507:       sin!(z)
508:     else
509:       Complex(sin!(z.real)*cosh!(z.image),
510:               cos!(z.real)*sinh!(z.image))
511:     end
512:   end

[Source]

     # File lib/complex.rb, line 523
523:   def sinh(z)
524:     if Complex.generic?(z)
525:       sinh!(z)
526:     else
527:       Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) )
528:     end
529:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 467
467:   def sqrt(z)
468:     if Complex.generic?(z)
469:       if z >= 0
470:         sqrt!(z)
471:       else
472:         Complex(0,sqrt!(-z))
473:       end
474:     else
475:       if z.image < 0
476:         sqrt(z.conjugate).conjugate
477:       else
478:         r = z.abs
479:         x = z.real
480:         Complex( sqrt!((r+x)/2), sqrt!((r-x)/2) )
481:       end
482:     end
483:   end

[Source]

     # File lib/mathn.rb, line 233
233:   def sqrt(a)
234:     if a.kind_of?(Complex)
235:       abs = sqrt(a.real*a.real + a.image*a.image)
236: #      if not abs.kind_of?(Rational)
237: #       return a**Rational(1,2)
238: #      end
239:       x = sqrt((a.real + abs)/Rational(2))
240:       y = sqrt((-a.real + abs)/Rational(2))
241: #      if !(x.kind_of?(Rational) and y.kind_of?(Rational))
242: #       return a**Rational(1,2)
243: #      end
244:       if a.image >= 0 
245:         Complex(x, y)
246:       else
247:         Complex(x, -y)
248:       end
249:     elsif a >= 0
250:       rsqrt(a)
251:     else
252:       Complex(0,rsqrt(-a))
253:     end
254:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 515
515:   def tan(z)
516:     if Complex.generic?(z)
517:       tan!(z)
518:     else
519:       sin(z)/cos(z)
520:     end
521:   end

[Source]

     # File lib/complex.rb, line 539
539:   def tanh(z)
540:     if Complex.generic?(z)
541:       tanh!(z)
542:     else
543:       sinh(z)/cosh(z)
544:     end
545:   end

[Validate]