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

Commit 447ad60

Browse files
committed
switch the algorithm
1 parent a8069e5 commit 447ad60

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

src/math/generic/floor.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,60 @@
11
/* SPDX-License-Identifier: MIT
22
* origin: musl src/math/floor.c */
33

4-
use super::super::{Float, Int};
4+
use super::super::{Float, Int, IntTy, MinInt};
55

66
pub fn floor<F: Float>(x: F) -> F {
7-
let toint = F::ONE / F::EPSILON;
7+
let zero = IntTy::<F>::ZERO;
88

9-
let e = x.exp().unsigned();
9+
let mut ix = x.to_bits();
10+
let e = x.exp_unbiased();
1011

11-
if e >= F::SIG_BITS + F::EXP_BIAS || x == F::ZERO {
12+
// If the represented value has no fractional part, no truncation is needed.
13+
if e >= F::SIG_BITS as i32 {
1214
return x;
1315
}
1416

15-
let neg = x.is_sign_negative();
17+
if e >= 0 {
18+
let m = F::SIG_MASK >> e.unsigned();
19+
if ix & m == zero {
20+
return x;
21+
}
22+
23+
force_eval!(x + F::MAX);
24+
25+
if x.is_sign_negative() {
26+
ix += m;
27+
}
28+
29+
ix &= !m;
30+
} else {
31+
force_eval!(x + F::MAX);
1632

17-
let y = if neg { x - toint + toint - x } else { x + toint - toint - x };
18-
if e < F::EXP_BIAS {
19-
force_eval!(y);
20-
return if neg { F::NEG_ONE } else { F::ZERO };
33+
if x.is_sign_positive() {
34+
ix = F::ZERO.to_bits();
35+
} else if ix << 1 != zero {
36+
ix = F::NEG_ONE.to_bits();
37+
}
2138
}
22-
if y > F::ZERO { x + y - F::ONE } else { x + y }
39+
40+
F::from_bits(ix)
41+
42+
// let toint = F::ONE / F::EPSILON;
43+
44+
// let e = x.exp().unsigned();
45+
46+
// if e >= F::SIG_BITS + F::EXP_BIAS || x == F::ZERO {
47+
// return x;
48+
// }
49+
50+
// let neg = x.is_sign_negative();
51+
52+
// let y = if neg { x - toint + toint - x } else { x + toint - toint - x };
53+
// if e < F::EXP_BIAS {
54+
// force_eval!(y);
55+
// return if neg { F::NEG_ONE } else { F::ZERO };
56+
// }
57+
// if y > F::ZERO { x + y - F::ONE } else { x + y }
2358
}
2459

2560
// // NB: using `exp` here and comparing to values adjusted by `EXP_BIAS` has better

0 commit comments

Comments
 (0)