Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 1c07ae0

Browse files
committed
wip
1 parent ba13e84 commit 1c07ae0

File tree

1 file changed

+49
-34
lines changed

1 file changed

+49
-34
lines changed

src/math/hypot.rs

+49-34
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
/*
2-
Copyright (c) 2022 Alexei Sibidanov.
3-
4-
This file is part of the CORE-MATH project
5-
(https://core-math.gitlabpages.inria.fr/).
6-
*/
1+
/* SPDX-License-Identifier: MIT */
2+
/* origin: core-math/src/binary64/hypot/hypot.c
3+
* Copyright (c) 2022 Alexei Sibidanov.
4+
* Ported to Rust in 2025 by Trevor Gross.
5+
*/
6+
7+
//! Euclidian distance via the pythagorean theorem (`√(x2 + y2)`).
8+
//!
9+
//! Per IEEE 754-2019:
10+
//!
11+
//! - Domain: `[−∞, +∞] × [−∞, +∞]`
12+
//! - `hypot(±0, ±0)` is +0
13+
//! - `hypot(±∞, qNaN)` is +∞
14+
//! - `hypot(qNaN, ±∞)` is +∞.
15+
//! - May raise overflow or underflow
716
817
use super::sqrt;
18+
use super::support::cold_path;
919

1020
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
1121
pub fn hypot(x: f64, y: f64) -> f64 {
@@ -22,9 +32,11 @@ fn cr_hypot(mut x: f64, mut y: f64) -> f64 {
2232
let mut ex: u64 = xi & emsk;
2333
let mut ey: u64 = yi & emsk;
2434
/* emsk corresponds to the upper bits of NaN and Inf (apart the sign bit) */
25-
x = __builtin_fabs(x);
26-
y = __builtin_fabs(y);
27-
if __builtin_expect(ex == emsk || ey == emsk, false) {
35+
x = x.abs();
36+
y = y.abs();
37+
if ex == emsk || ey == emsk {
38+
cold_path();
39+
2840
/* Either x or y is NaN or Inf */
2941
let wx: u64 = xi << 1;
3042
let wy: u64 = yi << 1;
@@ -46,14 +58,18 @@ fn cr_hypot(mut x: f64, mut y: f64) -> f64 {
4658
let mut yd: u64 = v.to_bits();
4759
ey = yd;
4860

49-
if __builtin_expect(ey >> 52 == 0, false) {
61+
if ey >> 52 == 0 {
62+
cold_path();
63+
5064
if yd == 0 {
5165
return f64::from_bits(xd);
5266
}
5367

5468
ex = xd;
5569

56-
if __builtin_expect(ex >> 52 == 0, false) {
70+
if ex >> 52 == 0 {
71+
cold_path();
72+
5773
if ex == 0 {
5874
return 0.0;
5975
}
@@ -70,7 +86,8 @@ fn cr_hypot(mut x: f64, mut y: f64) -> f64 {
7086
}
7187

7288
let de: u64 = xd.wrapping_sub(yd);
73-
if __builtin_expect(de > (27_u64 << 52), false) {
89+
if de > (27_u64 << 52) {
90+
cold_path();
7491
return __builtin_fma(hf64!("0x1p-27"), v, u);
7592
}
7693

@@ -98,14 +115,13 @@ fn cr_hypot(mut x: f64, mut y: f64) -> f64 {
98115
ex &= 0x7ff_u64 << 52;
99116
let aidr: u64 = ey + (0x3fe_u64 << 52) - ex;
100117
let mid: u64 = (aidr.wrapping_sub(0x3c90000000000000) + 16) >> 5;
101-
if __builtin_expect(
102-
mid == 0 || aidr < 0x39b0000000000000_u64 || aidr > 0x3c9fffffffffff80_u64,
103-
false,
104-
) {
118+
if mid == 0 || aidr < 0x39b0000000000000_u64 || aidr > 0x3c9fffffffffff80_u64 {
119+
cold_path();
105120
thd = as_hypot_hard(x, y, flag).to_bits();
106121
}
107122
thd = thd.wrapping_sub(off as u64);
108-
if __builtin_expect(thd >= (0x7ff_u64 << 52), false) {
123+
if thd >= (0x7ff_u64 << 52) {
124+
cold_path();
109125
return as_hypot_overflow();
110126
}
111127

@@ -169,8 +185,6 @@ fn as_hypot_hard(x: f64, y: f64, flag: FExcept) -> f64 {
169185
ls *= 2;
170186
m2 += (lm2 >> -ls) as u64;
171187
m2 |= ((lm2 << (128 + ls)) != 0) as u64;
172-
extern crate std;
173-
std::println!("here");
174188
}
175189

176190
let k: i32 = bs + re;
@@ -179,7 +193,7 @@ fn as_hypot_hard(x: f64, y: f64, flag: FExcept) -> f64 {
179193
loop {
180194
rm += 1 + (rm >= (1u64 << 53)) as u64;
181195
let tm: u64 = rm << k;
182-
let rm2: u64 = tm * tm;
196+
let rm2: u64 = tm.wrapping_mul(tm);
183197
d = m2 as i64 - rm2 as i64;
184198

185199
if d <= 0 {
@@ -192,10 +206,10 @@ fn as_hypot_hard(x: f64, y: f64, flag: FExcept) -> f64 {
192206
} else {
193207
if __builtin_expect(op == om, true) {
194208
let tm: u64 = (rm << k) - (1 << (k - (rm <= (1u64 << 53)) as i32));
195-
d = m2 as i64 - (tm * tm) as i64;
209+
d = m2 as i64 - (tm.wrapping_mul(tm)) as i64;
196210

197211
if __builtin_expect(d != 0, true) {
198-
rm += d as u64 >> 63;
212+
rm = rm.wrapping_add((d >> 63) as u64);
199213
} else {
200214
rm -= rm & 1;
201215
}
@@ -239,25 +253,31 @@ fn as_hypot_denorm(mut a: u64, mut b: u64) -> f64 {
239253
p_d = d;
240254
rm = rm.wrapping_add(drm as u64);
241255
d = d.wrapping_sub(dd);
242-
dd = d.wrapping_add(8);
243-
if !__builtin_expect((d ^ p_d) > 0, false) {
256+
dd = dd.wrapping_add(8);
257+
if (d ^ p_d) <= 0 {
258+
cold_path();
244259
break;
245260
}
246261
}
247262
p_d = (sd & d) + (!sd & p_d);
248-
if __builtin_expect(p_d != 0, true) {
249-
if __builtin_expect(op == om, true) {
250-
let sum: i64 = p_d.wrapping_sub(4_i64.wrapping_mul(rm as i64)).wrapping_sub(1);
263+
if p_d != 0 {
264+
if op == om {
265+
let sum: i64 = p_d.wrapping_sub(4u64.wrapping_mul(rm) as i64).wrapping_sub(1);
251266

252-
if __builtin_expect(sum != 0, true) {
253-
rm = rm.wrapping_add((sum as u64 >> 63) + 1);
267+
if sum != 0 {
268+
rm = rm.wrapping_add((sum >> 63).wrapping_add(1) as u64);
254269
} else {
270+
cold_path();
255271
rm += rm & 1;
256272
}
257273
} else {
274+
cold_path();
258275
rm += (op > 1.0) as u64;
259276
}
277+
} else {
278+
cold_path();
260279
}
280+
261281
let xi: u64 = rm;
262282
f64::from_bits(xi)
263283
}
@@ -280,11 +300,6 @@ fn __builtin_fma(x: f64, y: f64, z: f64) -> f64 {
280300

281301
type FExcept = u32;
282302

283-
fn get_rounding_mode(_flag: &mut FExcept) -> i32 {
284-
// Always nearest
285-
0
286-
}
287-
288303
fn set_flags(_flag: FExcept) {}
289304

290305
fn get_flags() -> FExcept {

0 commit comments

Comments
 (0)