Skip to content

Commit f9b5a97

Browse files
committed
Add prec validation and argument coerce in all BigMath methods
1 parent fc36408 commit f9b5a97

File tree

1 file changed

+38
-16
lines changed

1 file changed

+38
-16
lines changed

lib/bigdecimal/math.rb

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module BigMath
5454
# #=> "0.1414213562373095048801688724e1"
5555
#
5656
def sqrt(x, prec)
57+
x = BigMath._coerce_to_bigdecimal(x, :sqrt)
5758
x.sqrt(prec)
5859
end
5960

@@ -67,7 +68,8 @@ def sqrt(x, prec)
6768
# #=> "0.125992104989487316476721060727822e1"
6869
#
6970
def cbrt(x, prec)
70-
raise ArgumentError, "Zero or negative precision for cbrt" if prec <= 0
71+
BigMath._validate_prec(prec, :cbrt)
72+
x = BigMath._coerce_to_bigdecimal(x, :cbrt)
7173
return x if x.zero? || x.infinite? || x.nan?
7274
return -cbrt(-x, prec) if x < 0
7375

@@ -92,6 +94,8 @@ def cbrt(x, prec)
9294
# #=> "0.2236067977499789696409173668333333334e1"
9395
#
9496
def hypot(x, y, prec)
97+
BigMath._validate_prec(prec, :hypot)
98+
x = BigMath._coerce_to_bigdecimal(x, :hypot)
9599
return BigDecimal::NAN if x.nan? || y.nan?
96100
return BigDecimal::INFINITY if x.infinite? || y.infinite?
97101
prec2 = prec + BigDecimal.double_fig
@@ -110,7 +114,8 @@ def hypot(x, y, prec)
110114
# #=> "0.70710678118654752440082036563292800375e0"
111115
#
112116
def sin(x, prec)
113-
raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
117+
BigMath._validate_prec(prec, :sin)
118+
x = BigMath._coerce_to_bigdecimal(x, :sin)
114119
return BigDecimal("NaN") if x.infinite? || x.nan?
115120
n = prec + BigDecimal.double_fig
116121
one = BigDecimal("1")
@@ -156,7 +161,8 @@ def sin(x, prec)
156161
# #=> "-0.999999999999999999999999999999856613163740061349e0"
157162
#
158163
def cos(x, prec)
159-
raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
164+
BigMath._validate_prec(prec, :cos)
165+
x = BigMath._coerce_to_bigdecimal(x, :cos)
160166
return BigDecimal("NaN") if x.infinite? || x.nan?
161167
n = prec + BigDecimal.double_fig
162168
one = BigDecimal("1")
@@ -217,6 +223,8 @@ def cos(x, prec)
217223
# #=> "0.17320508075688772935274463415059e1"
218224
#
219225
def tan(x, prec)
226+
BigMath._validate_prec(prec, :tan)
227+
x = BigMath._coerce_to_bigdecimal(x, :tan)
220228
return BigDecimal(0) if x.zero?
221229

222230
# BigMath calculates sin with relative precision only when x.abs is small
@@ -238,7 +246,8 @@ def tan(x, prec)
238246
# #=> "0.52359877559829887307710723054659e0"
239247
#
240248
def asin(x, prec)
241-
raise ArgumentError, "Zero or negative precision for asin" if prec <= 0
249+
BigMath._validate_prec(prec, :asin)
250+
x = BigMath._coerce_to_bigdecimal(x, :asin)
242251
raise Math::DomainError, "Out of domain argument for asin" if x < -1 || x > 1
243252
return BigDecimal::NAN if x.nan?
244253
prec2 = prec + BigDecimal.double_fig
@@ -263,7 +272,8 @@ def asin(x, prec)
263272
# #=> "0.10471975511965977461542144610932e1"
264273
#
265274
def acos(x, prec)
266-
raise ArgumentError, "Zero or negative precision for acos" if prec <= 0
275+
BigMath._validate_prec(prec, :acos)
276+
x = BigMath._coerce_to_bigdecimal(x, :acos)
267277
raise Math::DomainError, "Out of domain argument for acos" if x < -1 || x > 1
268278

269279
return PI(prec) / 2 - asin(x, prec) if x < 0
@@ -287,7 +297,8 @@ def acos(x, prec)
287297
# #=> "-0.785398163397448309615660845819878471907514682065e0"
288298
#
289299
def atan(x, prec)
290-
raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
300+
BigMath._validate_prec(prec, :atan)
301+
x = BigMath._coerce_to_bigdecimal(x, :atan)
291302
return BigDecimal("NaN") if x.nan?
292303
pi = PI(prec)
293304
x = -x if neg = x < 0
@@ -324,6 +335,9 @@ def atan(x, prec)
324335
# #=> "-0.785398163397448309615660845819878471907514682065e0"
325336
#
326337
def atan2(y, x, prec)
338+
BigMath._validate_prec(prec, :atan2)
339+
x = BigMath._coerce_to_bigdecimal(x, :atan2)
340+
y = BigMath._coerce_to_bigdecimal(y, :atan2)
327341
if x.infinite? || y.infinite?
328342
one = BigDecimal(1)
329343
zero = BigDecimal(0)
@@ -356,7 +370,8 @@ def atan2(y, x, prec)
356370
# #=> "0.11752011936438014568823818505956e1"
357371
#
358372
def sinh(x, prec)
359-
raise ArgumentError, "Zero or negative precision for sinh" if prec <= 0
373+
BigMath._validate_prec(prec, :sinh)
374+
x = BigMath._coerce_to_bigdecimal(x, :sinh)
360375
return BigDecimal::NAN if x.nan?
361376
return x if x.infinite?
362377

@@ -378,7 +393,8 @@ def sinh(x, prec)
378393
# #=> "0.15430806348152437784779056207571e1"
379394
#
380395
def cosh(x, prec)
381-
raise ArgumentError, "Zero or negative precision for cosh" if prec <= 0
396+
BigMath._validate_prec(prec, :cosh)
397+
x = BigMath._coerce_to_bigdecimal(x, :cosh)
382398
return BigDecimal::NAN if x.nan?
383399
return BigDecimal::INFINITY if x.infinite?
384400

@@ -399,7 +415,8 @@ def cosh(x, prec)
399415
# #=> "0.7615941559557648881194582826048e0"
400416
#
401417
def tanh(x, prec)
402-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
418+
BigMath._validate_prec(prec, :tanh)
419+
x = BigMath._coerce_to_bigdecimal(x, :tanh)
403420
return BigDecimal::NAN if x.nan?
404421
return BigDecimal(x.infinite?) if x.infinite?
405422

@@ -422,7 +439,8 @@ def tanh(x, prec)
422439
# #=> "0.881373587019543025232609324892919887466177636058e0"
423440
#
424441
def asinh(x, prec)
425-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
442+
BigMath._validate_prec(prec, :asinh)
443+
x = BigMath._coerce_to_bigdecimal(x, :asinh)
426444
return x if x.nan? || x.infinite?
427445
return -asinh(-x, prec) if x < 0
428446

@@ -442,7 +460,8 @@ def asinh(x, prec)
442460
# #=> "0.1316957896924816708625046347239934461496535769096e1"
443461
#
444462
def acosh(x, prec)
445-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
463+
BigMath._validate_prec(prec, :acosh)
464+
x = BigMath._coerce_to_bigdecimal(x, :acosh)
446465
raise Math::DomainError, "Out of domain argument for acosh" if x < 1
447466
return BigDecimal::INFINITY if x.infinite?
448467
return BigDecimal::NAN if x.nan?
@@ -462,7 +481,8 @@ def acosh(x, prec)
462481
# #=> "0.54930614433405484569762261846126e0"
463482
#
464483
def atanh(x, prec)
465-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
484+
BigMath._validate_prec(prec, :atanh)
485+
x = BigMath._coerce_to_bigdecimal(x, :atanh)
466486
raise Math::DomainError, "Out of domain argument for atanh" if x < -1 || x > 1
467487
return BigDecimal::NAN if x.nan?
468488
return BigDecimal::INFINITY if x == 1
@@ -488,7 +508,8 @@ def atanh(x, prec)
488508
# #=> "0.158496250072115618145373894394782e1"
489509
#
490510
def log2(x, prec)
491-
raise ArgumentError, "Zero or negative precision for log2" if prec <= 0
511+
BigMath._validate_prec(prec, :log2)
512+
x = BigMath._coerce_to_bigdecimal(x, :log2, true)
492513
return BigDecimal::NAN if x.nan?
493514
return BigDecimal::INFINITY if x.infinite? == 1
494515

@@ -513,7 +534,8 @@ def log2(x, prec)
513534
# #=> "0.47712125471966243729502790325512e0"
514535
#
515536
def log10(x, prec)
516-
raise ArgumentError, "Zero or negative precision for log10" if prec <= 0
537+
BigMath._validate_prec(prec, :log10)
538+
x = BigMath._coerce_to_bigdecimal(x, :log10, true)
517539
return BigDecimal::NAN if x.nan?
518540
return BigDecimal::INFINITY if x.infinite? == 1
519541

@@ -532,7 +554,7 @@ def log10(x, prec)
532554
# #=> "0.3141592653589793238462643388813853786957412e1"
533555
#
534556
def PI(prec)
535-
raise ArgumentError, "Zero or negative precision for PI" if prec <= 0
557+
BigMath._validate_prec(prec, :PI)
536558
n = prec + BigDecimal.double_fig
537559
zero = BigDecimal("0")
538560
one = BigDecimal("1")
@@ -577,7 +599,7 @@ def PI(prec)
577599
# #=> "0.271828182845904523536028752390026306410273e1"
578600
#
579601
def E(prec)
580-
raise ArgumentError, "Zero or negative precision for E" if prec <= 0
602+
BigMath._validate_prec(prec, :E)
581603
BigMath.exp(1, prec)
582604
end
583605
end

0 commit comments

Comments
 (0)