Skip to content

Commit

Permalink
Merge pull request #406 from timcraft/math
Browse files Browse the repository at this point in the history
Implement Math functions
  • Loading branch information
seven1m authored Jan 11, 2022
2 parents db8b583 + b8696ac commit 4342d4b
Show file tree
Hide file tree
Showing 27 changed files with 1,405 additions and 0 deletions.
56 changes: 56 additions & 0 deletions spec/core/math/acos_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

# arccosine : (-1.0, 1.0) --> (0, PI)
describe "Math.acos" do
before :each do
ScratchPad.clear
end

it "returns a float" do
Math.acos(1).should be_kind_of(Float )
end

it "returns the arccosine of the argument" do
Math.acos(1).should be_close(0.0, TOLERANCE)
Math.acos(0).should be_close(1.5707963267949, TOLERANCE)
Math.acos(-1).should be_close(Math::PI,TOLERANCE)
Math.acos(0.25).should be_close(1.31811607165282, TOLERANCE)
Math.acos(0.50).should be_close(1.0471975511966 , TOLERANCE)
Math.acos(0.75).should be_close(0.722734247813416, TOLERANCE)
end

it "raises an Math::DomainError if the argument is greater than 1.0" do
-> { Math.acos(1.0001) }.should raise_error(Math::DomainError)
end

it "raises an Math::DomainError if the argument is less than -1.0" do
-> { Math.acos(-1.0001) }.should raise_error(Math::DomainError)
end

it "raises a TypeError if the string argument cannot be coerced with Float()" do
-> { Math.acos("test") }.should raise_error(TypeError)
end

it "returns NaN given NaN" do
Math.acos(nan_value).nan?.should be_true
end

it "raises a TypeError if the argument cannot be coerced with Float()" do
-> { Math.acos(MathSpecs::UserClass.new) }.should raise_error(TypeError)
end

it "raises a TypeError if the argument is nil" do
-> { Math.acos(nil) }.should raise_error(TypeError)
end

it "accepts any argument that can be coerced with Float()" do
Math.acos(MathSpecs::Float.new(0.5)).should be_close(Math.acos(0.5), TOLERANCE)
end
end

describe "Math#acos" do
it "is accessible as a private instance method" do
IncludesMath.new.send(:acos, 0).should be_close(1.5707963267949, TOLERANCE)
end
end
41 changes: 41 additions & 0 deletions spec/core/math/acosh_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

describe "Math.acosh" do
it "returns a float" do
Math.acosh(1.0).should be_kind_of(Float)
end

it "returns the principle value of the inverse hyperbolic cosine of the argument" do
Math.acosh(14.2).should be_close(3.345146999647, TOLERANCE)
Math.acosh(1.0).should be_close(0.0, TOLERANCE)
end

it "raises Math::DomainError if the passed argument is less than -1.0 or greater than 1.0" do
-> { Math.acosh(1.0 - TOLERANCE) }.should raise_error(Math::DomainError)
-> { Math.acosh(0) }.should raise_error(Math::DomainError)
-> { Math.acosh(-1.0) }.should raise_error(Math::DomainError)
end

it "raises a TypeError if the argument cannot be coerced with Float()" do
-> { Math.acosh("test") }.should raise_error(TypeError)
end

it "returns NaN given NaN" do
Math.acosh(nan_value).nan?.should be_true
end

it "raises a TypeError if the argument is nil" do
-> { Math.acosh(nil) }.should raise_error(TypeError)
end

it "accepts any argument that can be coerced with Float()" do
Math.acosh(MathSpecs::Float.new).should == 0.0
end
end

describe "Math#acosh" do
it "is accessible as a private instance method" do
IncludesMath.new.send(:acosh, 1.0).should be_close(0.0, TOLERANCE)
end
end
48 changes: 48 additions & 0 deletions spec/core/math/asin_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

# arcsine : (-1.0, 1.0) --> (-PI/2, PI/2)
describe "Math.asin" do
it "returns a float" do
Math.asin(1).should be_kind_of(Float)
end

it "returns the arcsine of the argument" do
Math.asin(1).should be_close(Math::PI/2, TOLERANCE)
Math.asin(0).should be_close(0.0, TOLERANCE)
Math.asin(-1).should be_close(-Math::PI/2, TOLERANCE)
Math.asin(0.25).should be_close(0.252680255142079, TOLERANCE)
Math.asin(0.50).should be_close(0.523598775598299, TOLERANCE)
Math.asin(0.75).should be_close(0.8480620789814816,TOLERANCE)
end

it "raises an Math::DomainError if the argument is greater than 1.0" do
-> { Math.asin(1.0001) }.should raise_error( Math::DomainError)
end

it "raises an Math::DomainError if the argument is less than -1.0" do
-> { Math.asin(-1.0001) }.should raise_error( Math::DomainError)
end

it "raises a TypeError if the argument cannot be coerced with Float()" do
-> { Math.asin("test") }.should raise_error(TypeError)
end

it "returns NaN given NaN" do
Math.asin(nan_value).nan?.should be_true
end

it "raises a TypeError if the argument is nil" do
-> { Math.asin(nil) }.should raise_error(TypeError)
end

it "accepts any argument that can be coerced with Float()" do
Math.asin(MathSpecs::Float.new).should be_close(1.5707963267949, TOLERANCE)
end
end

describe "Math#asin" do
it "is accessible as a private instance method" do
IncludesMath.new.send(:asin, 0.5).should be_close(0.523598775598299, TOLERANCE)
end
end
42 changes: 42 additions & 0 deletions spec/core/math/asinh_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

describe "Math.asinh" do
it "returns a float" do
Math.asinh(1.5).should be_kind_of(Float)
end

it "returns the inverse hyperbolic sin of the argument" do
Math.asinh(1.5).should be_close(1.19476321728711, TOLERANCE)
Math.asinh(-2.97).should be_close(-1.8089166921397, TOLERANCE)
Math.asinh(0.0).should == 0.0
Math.asinh(-0.0).should == -0.0
Math.asinh(1.05367e-08).should be_close(1.05367e-08, TOLERANCE)
Math.asinh(-1.05367e-08).should be_close(-1.05367e-08, TOLERANCE)
# Default tolerance does not scale right for these...
#Math.asinh(94906265.62).should be_close(19.0615, TOLERANCE)
#Math.asinh(-94906265.62).should be_close(-19.0615, TOLERANCE)
end

it "raises a TypeError if the argument cannot be coerced with Float()" do
-> { Math.asinh("test") }.should raise_error(TypeError)
end

it "returns NaN given NaN" do
Math.asinh(nan_value).nan?.should be_true
end

it "raises a TypeError if the argument is nil" do
-> { Math.asinh(nil) }.should raise_error(TypeError)
end

it "accepts any argument that can be coerced with Float()" do
Math.asinh(MathSpecs::Float.new).should be_close(0.881373587019543, TOLERANCE)
end
end

describe "Math#asinh" do
it "is accessible as a private instance method" do
IncludesMath.new.send(:asinh, 19.275).should be_close(3.65262832292466, TOLERANCE)
end
end
54 changes: 54 additions & 0 deletions spec/core/math/atan2_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

describe "Math.atan2" do
it "returns a float" do
Math.atan2(1.2, 0.5).should be_kind_of(Float)
end

it "returns the arc tangent of y, x" do
Math.atan2(4.2, 0.3).should be_close(1.49948886200961, TOLERANCE)
Math.atan2(0.0, 1.0).should be_close(0.0, TOLERANCE)
Math.atan2(-9.1, 3.2).should be_close(-1.23265379809025, TOLERANCE)
Math.atan2(7.22, -3.3).should be_close(1.99950888779256, TOLERANCE)
end

it "raises a TypeError if the argument cannot be coerced with Float()" do
-> { Math.atan2(1.0, "test") }.should raise_error(TypeError)
-> { Math.atan2("test", 0.0) }.should raise_error(TypeError)
-> { Math.atan2("test", "this") }.should raise_error(TypeError)
end

it "raises a TypeError if the argument is nil" do
-> { Math.atan2(nil, 1.0) }.should raise_error(TypeError)
-> { Math.atan2(-1.0, nil) }.should raise_error(TypeError)
-> { Math.atan2(nil, nil) }.should raise_error(TypeError)
end

it "accepts any argument that can be coerced with Float()" do
Math.atan2(MathSpecs::Float.new, MathSpecs::Float.new).should be_close(0.785398163397448, TOLERANCE)
end

it "returns positive zero when passed 0.0, 0.0" do
Math.atan2(0.0, 0.0).should be_positive_zero
end

it "returns negative zero when passed -0.0, 0.0" do
Math.atan2(-0.0, 0.0).should be_negative_zero
end

it "returns Pi when passed 0.0, -0.0" do
Math.atan2(0.0, -0.0).should == Math::PI
end

it "returns -Pi when passed -0.0, -0.0" do
Math.atan2(-0.0, -0.0).should == -Math::PI
end

end

describe "Math#atan2" do
it "is accessible as a private instance method" do
IncludesMath.new.send(:atan2, 1.1, 2.2).should be_close(0.463647609000806, TOLERANCE)
end
end
40 changes: 40 additions & 0 deletions spec/core/math/atan_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

# arctangent : (-Inf, Inf) --> (-PI/2, PI/2)
describe "Math.atan" do
it "returns a float" do
Math.atan(1).should be_kind_of(Float)
end

it "returns the arctangent of the argument" do
Math.atan(1).should be_close(Math::PI/4, TOLERANCE)
Math.atan(0).should be_close(0.0, TOLERANCE)
Math.atan(-1).should be_close(-Math::PI/4, TOLERANCE)
Math.atan(0.25).should be_close(0.244978663126864, TOLERANCE)
Math.atan(0.50).should be_close(0.463647609000806, TOLERANCE)
Math.atan(0.75).should be_close(0.643501108793284, TOLERANCE)
end

it "raises a TypeError if the argument cannot be coerced with Float()" do
-> { Math.atan("test") }.should raise_error(TypeError)
end

it "returns NaN given NaN" do
Math.atan(nan_value).nan?.should be_true
end

it "raises a TypeError if the argument is nil" do
-> { Math.atan(nil) }.should raise_error(TypeError)
end

it "accepts any argument that can be coerced with Float()" do
Math.atan(MathSpecs::Float.new).should be_close(0.785398163397448, TOLERANCE)
end
end

describe "Math#atan" do
it "is accessible as a private instance method" do
IncludesMath.new.send(:atan, 3.1415).should be_close(1.2626187313511, TOLERANCE)
end
end
14 changes: 14 additions & 0 deletions spec/core/math/atanh_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require_relative '../../spec_helper'
require_relative '../../fixtures/math/common'
require_relative '../../shared/math/atanh'

describe "Math.atanh" do
it_behaves_like :math_atanh_base, :atanh, Math
it_behaves_like :math_atanh_no_complex, :atanh, Math
end

describe "Math#atanh" do
it_behaves_like :math_atanh_private, :atanh
it_behaves_like :math_atanh_base, :atanh, IncludesMath.new
it_behaves_like :math_atanh_no_complex, :atanh, IncludesMath.new
end
27 changes: 27 additions & 0 deletions spec/core/math/cbrt_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

describe "Math.cbrt" do
it "returns a float" do
Math.cbrt(1).should be_an_instance_of(Float)
end

it "returns the cubic root of the argument" do
Math.cbrt(1).should == 1.0
Math.cbrt(8.0).should == 2.0
Math.cbrt(-8.0).should == -2.0
Math.cbrt(3).should be_close(1.44224957030741, TOLERANCE)
end

it "raises a TypeError if the argument cannot be coerced with Float()" do
-> { Math.cbrt("foobar") }.should raise_error(TypeError)
end

it "raises a TypeError if the argument is nil" do
-> { Math.cbrt(nil) }.should raise_error(TypeError)
end

it "accepts any argument that can be coerced with Float()" do
Math.cbrt(MathSpecs::Float.new).should be_close(1.0, TOLERANCE)
end
end
42 changes: 42 additions & 0 deletions spec/core/math/cos_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

# cosine : (-Inf, Inf) --> (-1.0, 1.0)
describe "Math.cos" do
it "returns a float" do
Math.cos(Math::PI).should be_kind_of(Float)
end

it "returns the cosine of the argument expressed in radians" do
Math.cos(Math::PI).should be_close(-1.0, TOLERANCE)
Math.cos(0).should be_close(1.0, TOLERANCE)
Math.cos(Math::PI/2).should be_close(0.0, TOLERANCE)
Math.cos(3*Math::PI/2).should be_close(0.0, TOLERANCE)
Math.cos(2*Math::PI).should be_close(1.0, TOLERANCE)
end


it "raises a TypeError unless the argument is Numeric and has #to_f" do
-> { Math.cos("test") }.should raise_error(TypeError)
end

it "returns NaN given NaN" do
Math.cos(nan_value).nan?.should be_true
end

it "raises a TypeError if the argument is nil" do
-> { Math.cos(nil) }.should raise_error(TypeError)
end

it "coerces its argument with #to_f" do
f = mock_numeric('8.2')
f.should_receive(:to_f).and_return(8.2)
Math.cos(f).should == Math.cos(8.2)
end
end

describe "Math#cos" do
it "is accessible as a private instance method" do
IncludesMath.new.send(:cos, 3.1415).should be_close(-0.999999995707656, TOLERANCE)
end
end
Loading

0 comments on commit 4342d4b

Please sign in to comment.