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 562
562:   def acos(z)
563:     if Complex.generic?(z) and z >= -1 and z <= 1
564:       acos!(z)
565:     else
566:       -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) )
567:     end
568:   end

[Source]

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

[Source]

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

[Source]

     # File lib/complex.rb, line 602
602:   def asinh(z)
603:     if Complex.generic?(z)
604:       asinh!(z)
605:     else
606:       log( z + sqrt(1.0+z*z) )
607:     end
608:   end

[Source]

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

[Source]

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

[Source]

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

Redefined to handle a Complex argument.

[Source]

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

[Source]

     # File lib/complex.rb, line 527
527:   def cosh(z)
528:     if Complex.generic?(z)
529:       cosh!(z)
530:     else
531:       Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) )
532:     end
533:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 482
482:   def exp(z)
483:     if Complex.generic?(z)
484:       exp!(z)
485:     else
486:       Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))
487:     end
488:   end

Redefined to handle a Complex argument.

[Source]

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

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 554
554:   def log10(z)
555:     if Complex.generic?(z)
556:       log10!(z)
557:     else
558:       log(z)/log!(10)
559:     end
560:   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 501
501:   def sin(z)
502:     if Complex.generic?(z)
503:       sin!(z)
504:     else
505:       Complex(sin!(z.real)*cosh!(z.image),
506:               cos!(z.real)*sinh!(z.image))
507:     end
508:   end

[Source]

     # File lib/complex.rb, line 519
519:   def sinh(z)
520:     if Complex.generic?(z)
521:       sinh!(z)
522:     else
523:       Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) )
524:     end
525:   end

Redefined to handle a Complex argument.

[Source]

     # File lib/complex.rb, line 463
463:   def sqrt(z)
464:     if Complex.generic?(z)
465:       if z >= 0
466:         sqrt!(z)
467:       else
468:         Complex(0,sqrt!(-z))
469:       end
470:     else
471:       if z.image < 0
472:         sqrt(z.conjugate).conjugate
473:       else
474:         r = z.abs
475:         x = z.real
476:         Complex( sqrt!((r+x)/2), sqrt!((r-x)/2) )
477:       end
478:     end
479:   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 511
511:   def tan(z)
512:     if Complex.generic?(z)
513:       tan!(z)
514:     else
515:       sin(z)/cos(z)
516:     end
517:   end

[Source]

     # File lib/complex.rb, line 535
535:   def tanh(z)
536:     if Complex.generic?(z)
537:       tanh!(z)
538:     else
539:       sinh(z)/cosh(z)
540:     end
541:   end

[Validate]