Skip to content

Commit e0a0da4

Browse files
author
Robin Kruppe
committed
---
yaml --- r: 232339 b: refs/heads/try c: 15518a9 h: refs/heads/master i: 232337: 61abe54 232335: 8bdb844 v: v3
1 parent 60016fd commit e0a0da4

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: edeb4f1c86cbf6af8ef9874d4b3af50f721ea1b8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 82dbc2ea619cbfc98ca9ad2f9e06a5acd294cbe3
4+
refs/heads/try: 15518a9c0c1c5f1774503c72072c73e64411d130
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/libcore/num/dec2flt/algorithm.rs

Lines changed: 11 additions & 3 deletions
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,

branches/try/src/libcoretest/num/dec2flt/mod.rs

Lines changed: 7 additions & 0 deletions
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)