Charles L. Dorian | 067fe28 | 2010-03-05 16:45:39 -0800 | [diff] [blame] | 1 | // Copyright 2010 The Go Authors. All rights reserved. |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
Rob Pike | 4331293 | 2008-06-27 17:06:23 -0700 | [diff] [blame] | 5 | package math |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 6 | |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 7 | /* |
Rob Pike | 00e2cda | 2010-01-12 07:38:31 +1100 | [diff] [blame] | 8 | Hypot -- sqrt(p*p + q*q), but overflows only if the result does. |
Rob Pike | 00e2cda | 2010-01-12 07:38:31 +1100 | [diff] [blame] | 9 | */ |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 10 | |
Charles L. Dorian | f273487 | 2012-04-06 14:01:12 -0400 | [diff] [blame] | 11 | // Hypot returns Sqrt(p*p + q*q), taking care to avoid |
Russ Cox | dfc3910 | 2009-03-05 13:31:01 -0800 | [diff] [blame] | 12 | // unnecessary overflow and underflow. |
Charles L. Dorian | 9a6b8e2 | 2010-01-15 13:21:47 -0800 | [diff] [blame] | 13 | // |
| 14 | // Special cases are: |
Russ Cox | 1930977 | 2022-02-03 14:12:08 -0500 | [diff] [blame] | 15 | // |
Russ Cox | 60a1f54 | 2013-03-25 17:01:40 -0400 | [diff] [blame] | 16 | // Hypot(±Inf, q) = +Inf |
| 17 | // Hypot(p, ±Inf) = +Inf |
| 18 | // Hypot(NaN, q) = NaN |
| 19 | // Hypot(p, NaN) = NaN |
Austin Clements | 1d20a36 | 2021-04-14 21:57:24 -0400 | [diff] [blame] | 20 | func Hypot(p, q float64) float64 { |
| 21 | if haveArchHypot { |
| 22 | return archHypot(p, q) |
| 23 | } |
| 24 | return hypot(p, q) |
| 25 | } |
Russ Cox | dd8dc6f | 2011-12-13 15:20:12 -0500 | [diff] [blame] | 26 | |
Russ Cox | 2572803 | 2011-12-13 17:08:56 -0500 | [diff] [blame] | 27 | func hypot(p, q float64) float64 { |
eric fang | dd7ce26 | 2022-06-29 03:09:54 +0000 | [diff] [blame] | 28 | p, q = Abs(p), Abs(q) |
Charles L. Dorian | 9a6b8e2 | 2010-01-15 13:21:47 -0800 | [diff] [blame] | 29 | // special cases |
| 30 | switch { |
eric fang | dd7ce26 | 2022-06-29 03:09:54 +0000 | [diff] [blame] | 31 | case IsInf(p, 1) || IsInf(q, 1): |
Charles L. Dorian | 9a6b8e2 | 2010-01-15 13:21:47 -0800 | [diff] [blame] | 32 | return Inf(1) |
Luuk van Dijk | 8dd3de4 | 2012-02-01 16:08:31 +0100 | [diff] [blame] | 33 | case IsNaN(p) || IsNaN(q): |
Charles L. Dorian | 9a6b8e2 | 2010-01-15 13:21:47 -0800 | [diff] [blame] | 34 | return NaN() |
| 35 | } |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 36 | if p < q { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 37 | p, q = q, p |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 38 | } |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 39 | if p == 0 { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 40 | return 0 |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 41 | } |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 42 | q = q / p |
Charles L. Dorian | 067fe28 | 2010-03-05 16:45:39 -0800 | [diff] [blame] | 43 | return p * Sqrt(1+q*q) |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 44 | } |