Module: Math (Ruby 2.3.4)

In Files

  • mathn.rb

Methods

Class/Module Index [+]

Quicksearch

Math

When mathn is required, the Math module changes as follows:

Standard Math module behaviour:

Math.sqrt(4/9)     # => 0.0
Math.sqrt(4.0/9.0) # => 0.666666666666667
Math.sqrt(- 4/9)   # => Errno::EDOM: Numerical argument out of domain - sqrt

After require ‘mathn’, this is changed to:

require 'mathn'
Math.sqrt(4/9)      # => 2/3
Math.sqrt(4.0/9.0)  # => 0.666666666666667
Math.sqrt(- 4/9)    # => Complex(0, 2/3)

Public Class Methods

rsqrt(a)

Compute square root of a non negative number. This method is internally used by Math.sqrt.

 
               # File mathn.rb, line 142
def rsqrt(a)
  if a.kind_of?(Float)
    sqrt!(a)
  elsif a.kind_of?(Rational)
    rsqrt(a.numerator)/rsqrt(a.denominator)
  else
    src = a
    max = 2 ** 32
    byte_a = [src & 0xffffffff]
    # ruby's bug
    while (src >= max) and (src >>= 32)
      byte_a.unshift src & 0xffffffff
    end

    answer = 0
    main = 0
    side = 0
    for elm in byte_a
      main = (main << 32) + elm
      side <<= 16
      if answer != 0
        if main * 4  < side * side
          applo = main.div(side)
        else
          applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
        end
      else
        applo = sqrt!(main).to_i + 1
      end

      while (x = (side + applo) * applo) > main
        applo -= 1
      end
      main -= x
      answer = (answer << 16) + applo
      side += applo * 2
    end
    if main == 0
      answer
    else
      sqrt!(a)
    end
  end
end
            
sqrt(a)

Computes the square root of a. It makes use of Complex and Rational to have no rounding errors if possible.

Math.sqrt(4/9)      # => 2/3
Math.sqrt(- 4/9)    # => Complex(0, 2/3)
Math.sqrt(4.0/9.0)  # => 0.666666666666667
 
               # File mathn.rb, line 119
def sqrt(a)
  if a.kind_of?(Complex)
    abs = sqrt(a.real*a.real + a.imag*a.imag)
    x = sqrt((a.real + abs)/Rational(2))
    y = sqrt((-a.real + abs)/Rational(2))
    if a.imag >= 0
      Complex(x, y)
    else
      Complex(x, -y)
    end
  elsif a.respond_to?(:nan?) and a.nan?
    a
  elsif a >= 0
    rsqrt(a)
  else
    Complex(0,rsqrt(-a))
  end
end