Skip to content

Commit 15518a9

Browse files
author
Robin Kruppe
committed
Mention that the fast path is broken without SSE.
1 parent 82dbc2e commit 15518a9

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

src/libcore/num/dec2flt/algorithm.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ use super::num::{self, Big};
2121
/// Number of significand bits in Fp
2222
const P: u32 = 64;
2323

24-
// We simply store the best approximation for *all* exponents, so
25-
// the variable "h" and the associated conditions can be omitted.
26-
// This trades performance for space (11 KiB versus... 5 KiB or so?)
24+
// We simply store the best approximation for *all* exponents, so the variable "h" and the
25+
// associated conditions can be omitted. This trades performance for a couple kilobytes of space.
2726

2827
fn power_of_ten(e: i16) -> Fp {
2928
assert!(e >= table::MIN_E);
@@ -37,6 +36,15 @@ fn power_of_ten(e: i16) -> Fp {
3736
///
3837
/// This is extracted into a separate function so that it can be attempted before constructing
3938
/// a bignum.
39+
///
40+
/// The fast path crucially depends on arithmetic being correctly rounded, so on x86
41+
/// without SSE or SSE2 it will be **wrong** (as in, off by one ULP occasionally), because the x87
42+
/// FPU stack will round to 80 bit first before rounding to 64/32 bit. However, as such hardware
43+
/// is extremely rare nowadays and in fact all in-tree target triples assume an SSE2-capable
44+
/// microarchitecture, there is little incentive to deal with that. There's a test that will fail
45+
/// when SSE or SSE2 is disabled, so people building their own non-SSE copy will get a heads up.
46+
///
47+
/// FIXME: It would nevertheless be nice if we had a good way to detect and deal with x87.
4048
pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Option<T> {
4149
let num_digits = integral.len() + fractional.len();
4250
// log_10(f64::max_sig) ~ 15.95. We compare the exact value to max_sig near the end,

src/libcoretest/num/dec2flt/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ fn zero() {
9090
test_literal!(1e-500);
9191
}
9292

93+
#[test]
94+
fn fast_path_correct() {
95+
// This number triggers the fast path and is handled incorrectly when compiling on
96+
// x86 without SSE2 (i.e., using the x87 FPU stack).
97+
test_literal!(1.448997445238699);
98+
}
99+
93100
#[test]
94101
fn lonely_dot() {
95102
assert_eq!(to_f64("."), Ok(0.0));

0 commit comments

Comments
 (0)