diff options
| author | gingerBill <bill@gingerbill.org> | 2023-06-28 12:16:49 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-06-28 12:16:49 +0100 |
| commit | 20e954a864ecd2e9da8d5df23739f1b83c59eb9a (patch) | |
| tree | 300e141790f179fb61c5c24b81adb43376d7ee70 | |
| parent | 03e40b333ad7eeaefe3e5904849304a6da79fbb7 (diff) | |
Add `math.hypot`
| -rw-r--r-- | core/math/math.odin | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/core/math/math.odin b/core/math/math.odin index 05177378f..70ffc1a35 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -2158,6 +2158,74 @@ signbit :: proc{ } +@(require_results) +hypot_f16 :: proc "contextless" (x, y: f16) -> (r: f16) { + switch { + case is_nan(x) || is_nan(y): + r = nan_f16() + case x == y: + r = x + case x == 0: + r = copy_sign_f16(1, y) + case (y > x) == (x > 0): + r = transmute(f16)(transmute(u16)x + 1) + case: + r = transmute(f16)(transmute(u16)x - 1) + } + return +} +@(require_results) +hypot_f32 :: proc "contextless" (x, y: f32) -> (r: f32) { + switch { + case is_nan(x) || is_nan(y): + r = nan_f32() + case x == y: + r = x + case x == 0: + r = copy_sign_f32(1, y) + case (y > x) == (x > 0): + r = transmute(f32)(transmute(u32)x + 1) + case: + r = transmute(f32)(transmute(u32)x - 1) + } + return +} +@(require_results) +hypot_f64 :: proc "contextless" (x, y: f64) -> (r: f64) { + switch { + case is_nan(x) || is_nan(y): + r = nan_f64() + case x == y: + r = x + case x == 0: + r = copy_sign_f64(1, y) + case (y > x) == (x > 0): + r = transmute(f64)(transmute(u64)x + 1) + case: + r = transmute(f64)(transmute(u64)x - 1) + } + return +} +@(require_results) hypot_f16le :: proc "contextless" (x, y: f16le) -> (r: f16le) { return f16le(hypot_f16(f16(x), f16(y))) } +@(require_results) hypot_f16be :: proc "contextless" (x, y: f16be) -> (r: f16be) { return f16be(hypot_f16(f16(x), f16(y))) } +@(require_results) hypot_f32le :: proc "contextless" (x, y: f32le) -> (r: f32le) { return f32le(hypot_f32(f32(x), f32(y))) } +@(require_results) hypot_f32be :: proc "contextless" (x, y: f32be) -> (r: f32be) { return f32be(hypot_f32(f32(x), f32(y))) } +@(require_results) hypot_f64le :: proc "contextless" (x, y: f64le) -> (r: f64le) { return f64le(hypot_f64(f64(x), f64(y))) } +@(require_results) hypot_f64be :: proc "contextless" (x, y: f64be) -> (r: f64be) { return f64be(hypot_f64(f64(x), f64(y))) } + +// hypot returns Sqrt(p*p + q*q), taking care to avoid unnecessary overflow and underflow. +// +// Special cases: +// hypot(±Inf, q) = +Inf +// hypot(p, ±Inf) = +Inf +// hypot(NaN, q) = NaN +// hypot(p, NaN) = NaN +hypot :: proc{ + hypot_f16, hypot_f16le, hypot_f16be, + hypot_f32, hypot_f32le, hypot_f32be, + hypot_f64, hypot_f64le, hypot_f64be, +} + F16_DIG :: 3 F16_EPSILON :: 0.00097656 F16_GUARD :: 0 |