// Copyright 2009-2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package math /* Hypot -- sqrt(p*p + q*q), but overflows only if the result does. See: Cleve Moler and Donald Morrison, Replacing Square Roots by Pythagorean Sums IBM Journal of Research and Development, Vol. 27, Number 6, pp. 577-581, Nov. 1983 */ // Hypot computes Sqrt(p*p + q*q), taking care to avoid // unnecessary overflow and underflow. // // Special cases are: // Hypot(p, q) = +Inf if p or q is infinite // Hypot(p, q) = NaN if p or q is NaN func hypotGo(p, q float64) float64 { // TODO(rsc): Remove manual inlining of IsNaN, IsInf // when compiler does it for us // special cases switch { case p < -MaxFloat64 || p > MaxFloat64 || q < -MaxFloat64 || q > MaxFloat64: // IsInf(p, 0) || IsInf(q, 0): return Inf(1) case p != p || q != q: // IsNaN(p) || IsNaN(q): return NaN() } if p < 0 { p = -p } if q < 0 { q = -q } if p < q { p, q = q, p } if p == 0 { return 0 } pfac := p q = q / p r := q p = 1 for { r = r * r s := r + 4 if s == 4 { return p * pfac } r = r / s p = p + 2*r*p q = q * r r = q / p } panic("unreachable") }