Skip to content

Commit 2fdbe4d

Browse files
committed
Implement BigMath.hypot(x, y, prec)
1 parent 0bccfda commit 2fdbe4d

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

lib/bigdecimal/math.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#--
66
# Contents:
77
# sqrt(x, prec)
8+
# hypot(x, y, prec)
89
# sin (x, prec)
910
# cos (x, prec)
1011
# tan (x, prec)
@@ -45,6 +46,22 @@ def sqrt(x, prec)
4546
x.sqrt(prec)
4647
end
4748

49+
# call-seq:
50+
# hypot(x, y, numeric) -> BigDecimal
51+
#
52+
# Returns sqrt(x**2 + y**2) to the specified number of digits of
53+
# precision, +numeric+.
54+
#
55+
# BigMath.hypot(BigDecimal('1'), BigDecimal('2'), 16).to_s
56+
# #=> "0.2236067977499789696409173668333333334e1"
57+
#
58+
def hypot(x, y, prec)
59+
return BigDecimal::NAN if x.nan? || y.nan?
60+
return BigDecimal::INFINITY if x.infinite? || y.infinite?
61+
prec2 = prec + BigDecimal.double_fig
62+
sqrt(x.mult(x, prec2) + y.mult(y, prec2), prec)
63+
end
64+
4865
# call-seq:
4966
# sin(decimal, numeric) -> BigDecimal
5067
#

test/bigdecimal/test_bigmath.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class TestBigMath < Test::Unit::TestCase
99
# SQRT in 116 (= 100 + double_fig) digits
1010
SQRT2 = BigDecimal("1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309123")
1111
SQRT3 = BigDecimal("1.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154067")
12+
SQRT5 = BigDecimal("2.2360679774997896964091736687312762354406183596115257242708972454105209256378048994144144083787822749695081761507738")
1213
PINF = BigDecimal("+Infinity")
1314
MINF = BigDecimal("-Infinity")
1415
NAN = BigDecimal("NaN")
@@ -33,6 +34,17 @@ def test_sqrt
3334
assert_relative_precision {|n| sqrt(BigDecimal("2e50"), n) }
3435
end
3536

37+
def test_hypot
38+
assert_in_delta(SQRT2, hypot(BigDecimal("1"), BigDecimal("1"), 100), BigDecimal("1e-100"))
39+
assert_in_delta(SQRT5, hypot(SQRT2, SQRT3, 100), BigDecimal("1e-100"))
40+
assert_equal(0, hypot(BigDecimal(0), BigDecimal(0), N))
41+
assert_equal(PINF, hypot(PINF, SQRT3, N))
42+
assert_equal(PINF, hypot(SQRT3, MINF, N))
43+
assert_relative_precision {|n| hypot(BigDecimal("1e-30"), BigDecimal("2e-30"), n) }
44+
assert_relative_precision {|n| hypot(BigDecimal("1.23"), BigDecimal("4.56"), n) }
45+
assert_relative_precision {|n| hypot(BigDecimal("2e30"), BigDecimal("1e30"), n) }
46+
end
47+
3648
def test_sin
3749
assert_in_delta(0.0, sin(BigDecimal("0.0"), N))
3850
assert_in_delta(Math.sqrt(2.0) / 2, sin(PI(N) / 4, N))

0 commit comments

Comments
 (0)