Skip to content

Commit cc95ba1

Browse files
committed
---
yaml --- r: 216801 b: refs/heads/stable c: 3d34e17 h: refs/heads/master i: 216799: c54a02a v: v3
1 parent e90ce62 commit cc95ba1

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ refs/heads/tmp: 378a370ff2057afeb1eae86eb6e78c476866a4a6
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: a5286998df566e736b32f6795bfc3803bdaf453d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: a641b05fda448d3388347838076e3c583a5f8fa4
32+
refs/heads/stable: 3d34e177dd19bfbc6885b03eac0632adc9c621b2
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375

branches/stable/src/libcore/num/flt2dec/strategy/dragon.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,11 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
307307
}
308308

309309
// rounding up if we stop in the middle of digits
310-
if mant >= *scale.mul_small(5) {
310+
// if the following digits are exactly 5000..., check the prior digit and try to
311+
// round to even (i.e. avoid rounding up when the prior digit is even).
312+
let order = mant.cmp(scale.mul_small(5));
313+
if order == Ordering::Greater || (order == Ordering::Equal &&
314+
(len == 0 || buf[len-1] & 1 == 1)) {
311315
// if rounding up changes the length, the exponent should also change.
312316
// but we've been requested a fixed number of digits, so do not alter the buffer...
313317
if let Some(c) = round_up(buf, len) {

branches/stable/src/libcoretest/num/flt2dec/mod.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,17 @@ fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16
105105
bytes::copy_memory(&expected[..i], &mut expected_);
106106
let mut expectedk_ = expectedk;
107107
if expected[i] >= b'5' {
108-
// if this returns true, expected_[..i] is all `9`s and being rounded up.
109-
// we should always return `100..00` (`i` digits) instead, since that's
110-
// what we can came up with `i` digits anyway. `round_up` assumes that
111-
// the adjustment to the length is done by caller, which we simply ignore.
112-
if let Some(_) = round_up(&mut expected_, i) { expectedk_ += 1; }
108+
// check if this is a rounding-to-even case.
109+
// we avoid rounding ...x5000... (with infinite zeroes) to ...(x+1) when x is even.
110+
if !(i+1 < expected.len() && expected[i-1] & 1 == 0 &&
111+
expected[i] == b'5' &&
112+
expected[i+1] == b' ') {
113+
// if this returns true, expected_[..i] is all `9`s and being rounded up.
114+
// we should always return `100..00` (`i` digits) instead, since that's
115+
// what we can came up with `i` digits anyway. `round_up` assumes that
116+
// the adjustment to the length is done by caller, which we simply ignore.
117+
if let Some(_) = round_up(&mut expected_, i) { expectedk_ += 1; }
118+
}
113119
}
114120

115121
try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk_;
@@ -243,6 +249,7 @@ pub fn f32_exact_sanity_test<F>(mut f: F)
243249
let minf32 = f32::ldexp(1.0, -149);
244250

245251
check_exact!(f(0.1f32) => b"100000001490116119384765625 ", 0);
252+
check_exact!(f(0.5f32) => b"5 ", 0);
246253
check_exact!(f(1.0f32/3.0) => b"3333333432674407958984375 ", 0);
247254
check_exact!(f(3.141592f32) => b"31415920257568359375 ", 1);
248255
check_exact!(f(3.141592e17f32) => b"314159196796878848 ", 18);
@@ -348,6 +355,7 @@ pub fn f64_exact_sanity_test<F>(mut f: F)
348355

349356
check_exact!(f(0.1f64) => b"1000000000000000055511151231257827021181", 0);
350357
check_exact!(f(0.45f64) => b"4500000000000000111022302462515654042363", 0);
358+
check_exact!(f(0.5f64) => b"5 ", 0);
351359
check_exact!(f(0.95f64) => b"9499999999999999555910790149937383830547", 0);
352360
check_exact!(f(100.0f64) => b"1 ", 3);
353361
check_exact!(f(999.5f64) => b"9995000000000000000000000000000000000000", 3);
@@ -1032,6 +1040,11 @@ pub fn to_exact_fixed_str_test<F>(mut f_: F)
10321040
assert_eq!(to_string(f, 999.5, Minus, 3, false), "999.500");
10331041
assert_eq!(to_string(f, 999.5, Minus, 30, false), "999.500000000000000000000000000000");
10341042

1043+
assert_eq!(to_string(f, 0.5, Minus, 0, false), "1");
1044+
assert_eq!(to_string(f, 0.5, Minus, 1, false), "0.5");
1045+
assert_eq!(to_string(f, 0.5, Minus, 2, false), "0.50");
1046+
assert_eq!(to_string(f, 0.5, Minus, 3, false), "0.500");
1047+
10351048
assert_eq!(to_string(f, 0.95, Minus, 0, false), "1");
10361049
assert_eq!(to_string(f, 0.95, Minus, 1, false), "0.9"); // because it really is less than 0.95
10371050
assert_eq!(to_string(f, 0.95, Minus, 2, false), "0.95");

0 commit comments

Comments
 (0)