Skip to content

Commit 1c37330

Browse files
committed
Add prec validation and argument coerce in all BigMath methods
1 parent 78d5122 commit 1c37330

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

@@ -95,6 +97,8 @@ def cbrt(x, prec)
9597
# #=> "0.2236067977499789696409173668333333334e1"
9698
#
9799
def hypot(x, y, prec)
100+
BigMath._validate_prec(prec, :hypot)
101+
x = BigMath._coerce_to_bigdecimal(x, :hypot)
98102
return BigDecimal::NAN if x.nan? || y.nan?
99103
return BigDecimal::INFINITY if x.infinite? || y.infinite?
100104
prec2 = prec + BigDecimal.double_fig
@@ -113,7 +117,8 @@ def hypot(x, y, prec)
113117
# #=> "0.70710678118654752440082036563292800375e0"
114118
#
115119
def sin(x, prec)
116-
raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
120+
BigMath._validate_prec(prec, :sin)
121+
x = BigMath._coerce_to_bigdecimal(x, :sin)
117122
return BigDecimal("NaN") if x.infinite? || x.nan?
118123
n = prec + BigDecimal.double_fig
119124
one = BigDecimal("1")
@@ -159,7 +164,8 @@ def sin(x, prec)
159164
# #=> "-0.999999999999999999999999999999856613163740061349e0"
160165
#
161166
def cos(x, prec)
162-
raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
167+
BigMath._validate_prec(prec, :cos)
168+
x = BigMath._coerce_to_bigdecimal(x, :cos)
163169
return BigDecimal("NaN") if x.infinite? || x.nan?
164170
n = prec + BigDecimal.double_fig
165171
one = BigDecimal("1")
@@ -220,6 +226,8 @@ def cos(x, prec)
220226
# #=> "0.17320508075688772935274463415059e1"
221227
#
222228
def tan(x, prec)
229+
BigMath._validate_prec(prec, :tan)
230+
x = BigMath._coerce_to_bigdecimal(x, :tan)
223231
return BigDecimal(0) if x.zero?
224232

225233
# BigMath calculates sin with relative precision only when x.abs is small
@@ -241,7 +249,8 @@ def tan(x, prec)
241249
# #=> "0.52359877559829887307710723054659e0"
242250
#
243251
def asin(x, prec)
244-
raise ArgumentError, "Zero or negative precision for asin" if prec <= 0
252+
BigMath._validate_prec(prec, :asin)
253+
x = BigMath._coerce_to_bigdecimal(x, :asin)
245254
raise Math::DomainError, "Out of domain argument for asin" if x < -1 || x > 1
246255
return BigDecimal::NAN if x.nan?
247256
prec2 = prec + BigDecimal.double_fig
@@ -266,7 +275,8 @@ def asin(x, prec)
266275
# #=> "0.10471975511965977461542144610932e1"
267276
#
268277
def acos(x, prec)
269-
raise ArgumentError, "Zero or negative precision for acos" if prec <= 0
278+
BigMath._validate_prec(prec, :acos)
279+
x = BigMath._coerce_to_bigdecimal(x, :acos)
270280
raise Math::DomainError, "Out of domain argument for acos" if x < -1 || x > 1
271281

272282
return PI(prec) / 2 - asin(x, prec) if x < 0
@@ -290,7 +300,8 @@ def acos(x, prec)
290300
# #=> "-0.785398163397448309615660845819878471907514682065e0"
291301
#
292302
def atan(x, prec)
293-
raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
303+
BigMath._validate_prec(prec, :atan)
304+
x = BigMath._coerce_to_bigdecimal(x, :atan)
294305
return BigDecimal("NaN") if x.nan?
295306
pi = PI(prec)
296307
x = -x if neg = x < 0
@@ -327,6 +338,9 @@ def atan(x, prec)
327338
# #=> "-0.785398163397448309615660845819878471907514682065e0"
328339
#
329340
def atan2(y, x, prec)
341+
BigMath._validate_prec(prec, :atan2)
342+
x = BigMath._coerce_to_bigdecimal(x, :atan2)
343+
y = BigMath._coerce_to_bigdecimal(y, :atan2)
330344
if x.infinite? || y.infinite?
331345
one = BigDecimal(1)
332346
zero = BigDecimal(0)
@@ -359,7 +373,8 @@ def atan2(y, x, prec)
359373
# #=> "0.11752011936438014568823818505956e1"
360374
#
361375
def sinh(x, prec)
362-
raise ArgumentError, "Zero or negative precision for sinh" if prec <= 0
376+
BigMath._validate_prec(prec, :sinh)
377+
x = BigMath._coerce_to_bigdecimal(x, :sinh)
363378
return BigDecimal::NAN if x.nan?
364379
return x if x.infinite?
365380

@@ -381,7 +396,8 @@ def sinh(x, prec)
381396
# #=> "0.15430806348152437784779056207571e1"
382397
#
383398
def cosh(x, prec)
384-
raise ArgumentError, "Zero or negative precision for cosh" if prec <= 0
399+
BigMath._validate_prec(prec, :cosh)
400+
x = BigMath._coerce_to_bigdecimal(x, :cosh)
385401
return BigDecimal::NAN if x.nan?
386402
return BigDecimal::INFINITY if x.infinite?
387403

@@ -402,7 +418,8 @@ def cosh(x, prec)
402418
# #=> "0.7615941559557648881194582826048e0"
403419
#
404420
def tanh(x, prec)
405-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
421+
BigMath._validate_prec(prec, :tanh)
422+
x = BigMath._coerce_to_bigdecimal(x, :tanh)
406423
return BigDecimal::NAN if x.nan?
407424
return BigDecimal(x.infinite?) if x.infinite?
408425

@@ -425,7 +442,8 @@ def tanh(x, prec)
425442
# #=> "0.881373587019543025232609324892919887466177636058e0"
426443
#
427444
def asinh(x, prec)
428-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
445+
BigMath._validate_prec(prec, :asinh)
446+
x = BigMath._coerce_to_bigdecimal(x, :asinh)
429447
return x if x.nan? || x.infinite?
430448
return -asinh(-x, prec) if x < 0
431449

@@ -445,7 +463,8 @@ def asinh(x, prec)
445463
# #=> "0.1316957896924816708625046347239934461496535769096e1"
446464
#
447465
def acosh(x, prec)
448-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
466+
BigMath._validate_prec(prec, :acosh)
467+
x = BigMath._coerce_to_bigdecimal(x, :acosh)
449468
raise Math::DomainError, "Out of domain argument for acosh" if x < 1
450469
return BigDecimal::INFINITY if x.infinite?
451470
return BigDecimal::NAN if x.nan?
@@ -465,7 +484,8 @@ def acosh(x, prec)
465484
# #=> "0.54930614433405484569762261846126e0"
466485
#
467486
def atanh(x, prec)
468-
raise ArgumentError, "Zero or negative precision for tanh" if prec <= 0
487+
BigMath._validate_prec(prec, :atanh)
488+
x = BigMath._coerce_to_bigdecimal(x, :atanh)
469489
raise Math::DomainError, "Out of domain argument for atanh" if x < -1 || x > 1
470490
return BigDecimal::NAN if x.nan?
471491
return BigDecimal::INFINITY if x == 1
@@ -491,7 +511,8 @@ def atanh(x, prec)
491511
# #=> "0.158496250072115618145373894394782e1"
492512
#
493513
def log2(x, prec)
494-
raise ArgumentError, "Zero or negative precision for log2" if prec <= 0
514+
BigMath._validate_prec(prec, :log2)
515+
x = BigMath._coerce_to_bigdecimal(x, :log2, true)
495516
return BigDecimal::NAN if x.nan?
496517
return BigDecimal::INFINITY if x.infinite? == 1
497518

@@ -516,7 +537,8 @@ def log2(x, prec)
516537
# #=> "0.47712125471966243729502790325512e0"
517538
#
518539
def log10(x, prec)
519-
raise ArgumentError, "Zero or negative precision for log10" if prec <= 0
540+
BigMath._validate_prec(prec, :log10)
541+
x = BigMath._coerce_to_bigdecimal(x, :log10, true)
520542
return BigDecimal::NAN if x.nan?
521543
return BigDecimal::INFINITY if x.infinite? == 1
522544

@@ -535,7 +557,7 @@ def log10(x, prec)
535557
# #=> "0.3141592653589793238462643388813853786957412e1"
536558
#
537559
def PI(prec)
538-
raise ArgumentError, "Zero or negative precision for PI" if prec <= 0
560+
BigMath._validate_prec(prec, :PI)
539561
n = prec + BigDecimal.double_fig
540562
zero = BigDecimal("0")
541563
one = BigDecimal("1")
@@ -580,7 +602,7 @@ def PI(prec)
580602
# #=> "0.271828182845904523536028752390026306410273e1"
581603
#
582604
def E(prec)
583-
raise ArgumentError, "Zero or negative precision for E" if prec <= 0
605+
BigMath._validate_prec(prec, :E)
584606
BigMath.exp(1, prec)
585607
end
586608
end

0 commit comments

Comments
 (0)