Module: Sevgi::Function::Math
- Included in:
- Sevgi::Function
- Defined in:
- lib/sevgi/function/math.rb
Overview
Numeric and trigonometric methods promoted to Sevgi::F. This module owns the public thread-local Math.precision configuration but is not otherwise a consumer mixin contract.
Constant Summary collapse
- PRECISION =
Default decimal precision used by approximate comparisons.
6
Class Method Summary collapse
-
.precision ⇒ Integer
Returns the current thread's default numeric precision.
-
.precision=(precision) ⇒ Integer?
Sets or clears the current thread's default numeric precision.
Instance Method Summary collapse
-
#acos(value) ⇒ Float
Returns the inverse cosine in degrees.
-
#acot(value) ⇒ Float
Returns the inverse cotangent in degrees.
-
#approx(float, precision = nil) ⇒ Numeric
Rounds a float with an explicit or thread-local precision.
-
#asin(value) ⇒ Float
Returns the inverse sine in degrees.
-
#atan(value) ⇒ Float
Returns the inverse tangent in degrees.
-
#atan2(y, x) ⇒ Float
Returns the quadrant-aware inverse tangent in degrees.
-
#cos(degrees) ⇒ Float
Returns the cosine of an angle expressed in degrees.
-
#cot(degrees) ⇒ Float
Returns the cotangent of an angle expressed in degrees.
-
#count(length, division) ⇒ Integer
Counts complete divisions in a length.
-
#eq?(left, right, precision: nil) ⇒ Boolean
Compares two numeric values after approximate rounding.
-
#ge?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is greater than or equal to the rounded right operand.
-
#gt?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is greater than the rounded right operand.
-
#le?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is less than or equal to the rounded right operand.
-
#lt?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is less than the rounded right operand.
-
#round(float, precision) ⇒ Numeric
Rounds a value only when precision is present.
-
#sin(degrees) ⇒ Float
Returns the sine of an angle expressed in degrees.
-
#tan(degrees) ⇒ Float
Returns the tangent of an angle expressed in degrees.
-
#to_degrees(radians) ⇒ Float
Converts radians to degrees.
-
#to_radians(degrees) ⇒ Float
Converts degrees to radians.
-
#with_precision(precision) { ... } ⇒ Object
Runs a block with a current-thread precision override.
-
#zero?(value, precision: nil) ⇒ Boolean
Checks whether a value is approximately zero.
Class Method Details
.precision ⇒ Integer
Returns the current thread's default numeric precision.
19 20 21 22 23 |
# File 'lib/sevgi/function/math.rb', line 19 def self.precision precision = Thread.current.thread_variable_get(PRECISION_KEY) precision.nil? ? PRECISION : precision end |
.precision=(precision) ⇒ Integer?
Sets or clears the current thread's default numeric precision.
29 30 31 32 33 34 35 |
# File 'lib/sevgi/function/math.rb', line 29 def self.precision=(precision) unless precision.nil? || precision.is_a?(::Integer) ArgumentError.("Precision must be an Integer or nil: #{precision.inspect}") end Thread.current.thread_variable_set(PRECISION_KEY, precision) end |
Instance Method Details
#acos(value) ⇒ Float
Returns the inverse cosine in degrees.
42 |
# File 'lib/sevgi/function/math.rb', line 42 def acos(value) = to_degrees(::Math.acos(finite_real(:value, value))) |
#acot(value) ⇒ Float
Returns the inverse cotangent in degrees.
48 |
# File 'lib/sevgi/function/math.rb', line 48 def acot(value) = 90.0 - to_degrees(::Math.atan(finite_real(:value, value))) |
#approx(float, precision = nil) ⇒ Numeric
Rounds a float with an explicit or thread-local precision.
55 56 57 58 |
# File 'lib/sevgi/function/math.rb', line 55 def approx(float, precision = nil) precision = precision.nil? ? Function::Math.precision : valid_precision(precision) valid_real(:value, float).round(precision) end |
#asin(value) ⇒ Float
Returns the inverse sine in degrees.
65 |
# File 'lib/sevgi/function/math.rb', line 65 def asin(value) = to_degrees(::Math.asin(finite_real(:value, value))) |
#atan(value) ⇒ Float
Returns the inverse tangent in degrees.
71 |
# File 'lib/sevgi/function/math.rb', line 71 def atan(value) = to_degrees(::Math.atan(finite_real(:value, value))) |
#atan2(y, x) ⇒ Float
Returns the quadrant-aware inverse tangent in degrees.
78 |
# File 'lib/sevgi/function/math.rb', line 78 def atan2(y, x) = to_degrees(::Math.atan2(finite_real(:y, y), finite_real(:x, x))) |
#cos(degrees) ⇒ Float
Returns the cosine of an angle expressed in degrees. Integer quarter turns return exact -1.0, 0.0, or
1.0; other angles use Ruby's floating-point Math implementation.
85 86 87 88 |
# File 'lib/sevgi/function/math.rb', line 85 def cos(degrees) degrees = finite_real(:degrees, degrees) quadrant_value(degrees, QUADRANT_COSINES) { ::Math.cos(radians(degrees)) } end |
#cot(degrees) ⇒ Float
Returns the cotangent of an angle expressed in degrees.
94 |
# File 'lib/sevgi/function/math.rb', line 94 def cot(degrees) = 1.0 / ::Math.tan(to_radians(degrees)) |
#count(length, division) ⇒ Integer
Counts complete divisions in a length.
101 102 103 104 105 106 107 |
# File 'lib/sevgi/function/math.rb', line 101 def count(length, division) length = finite_real(:length, length) divisor = finite_real(:division, division) ArgumentError.("Division must not be zero") if divisor.zero? (length / divisor).to_i end |
#eq?(left, right, precision: nil) ⇒ Boolean
Compares two numeric values after approximate rounding.
115 |
# File 'lib/sevgi/function/math.rb', line 115 def eq?(left, right, precision: nil) = approx(left, precision) == approx(right, precision) |
#ge?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is greater than or equal to the rounded right operand.
123 |
# File 'lib/sevgi/function/math.rb', line 123 def ge?(left, right, precision: nil) = approx(left, precision) >= approx(right, precision) |
#gt?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is greater than the rounded right operand.
131 |
# File 'lib/sevgi/function/math.rb', line 131 def gt?(left, right, precision: nil) = approx(left, precision) > approx(right, precision) |
#le?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is less than or equal to the rounded right operand.
139 |
# File 'lib/sevgi/function/math.rb', line 139 def le?(left, right, precision: nil) = approx(left, precision) <= approx(right, precision) |
#lt?(left, right, precision: nil) ⇒ Boolean
Checks whether the rounded left operand is less than the rounded right operand.
147 |
# File 'lib/sevgi/function/math.rb', line 147 def lt?(left, right, precision: nil) = approx(left, precision) < approx(right, precision) |
#round(float, precision) ⇒ Numeric
Rounds a value only when precision is present.
154 155 156 157 |
# File 'lib/sevgi/function/math.rb', line 154 def round(float, precision) number = valid_real(:value, float) precision.nil? ? number : number.round(valid_precision(precision)) end |
#sin(degrees) ⇒ Float
Returns the sine of an angle expressed in degrees. Integer quarter turns return exact -1.0, 0.0, or 1.0;
other angles use Ruby's floating-point Math implementation.
164 165 166 167 |
# File 'lib/sevgi/function/math.rb', line 164 def sin(degrees) degrees = finite_real(:degrees, degrees) quadrant_value(degrees, QUADRANT_SINES) { ::Math.sin(radians(degrees)) } end |
#tan(degrees) ⇒ Float
Returns the tangent of an angle expressed in degrees.
173 |
# File 'lib/sevgi/function/math.rb', line 173 def tan(degrees) = ::Math.tan(to_radians(degrees)) |
#to_degrees(radians) ⇒ Float
Converts radians to degrees.
179 |
# File 'lib/sevgi/function/math.rb', line 179 def to_degrees(radians) = finite_real(:radians, radians) * 180 / ::Math::PI |
#to_radians(degrees) ⇒ Float
Converts degrees to radians.
185 |
# File 'lib/sevgi/function/math.rb', line 185 def to_radians(degrees) = radians(finite_real(:degrees, degrees)) |
#with_precision(precision) { ... } ⇒ Object
Runs a block with a current-thread precision override.
197 198 199 200 201 202 203 204 205 |
# File 'lib/sevgi/function/math.rb', line 197 def with_precision(precision, &block) ArgumentError.("Block required") unless block previous = Thread.current.thread_variable_get(PRECISION_KEY) Function::Math.precision = precision block.call ensure Function::Math.precision = previous if block end |
#zero?(value, precision: nil) ⇒ Boolean
Checks whether a value is approximately zero.
212 |
# File 'lib/sevgi/function/math.rb', line 212 def zero?(value, precision: nil) = eq?(value, 0.0, precision:) |