diff options
| author | Kang Seonghoon <public+git@mearie.org> | 2015-05-06 21:11:14 +0900 |
|---|---|---|
| committer | Kang Seonghoon <public+git@mearie.org> | 2015-05-06 21:11:14 +0900 |
| commit | 3d34e177dd19bfbc6885b03eac0632adc9c621b2 (patch) | |
| tree | 7552928ee99af9f398ac719a2ce016e5e352835d /src/libcore/num | |
| parent | a641b05fda448d3388347838076e3c583a5f8fa4 (diff) | |
| download | rust-3d34e177dd19bfbc6885b03eac0632adc9c621b2.tar.gz rust-3d34e177dd19bfbc6885b03eac0632adc9c621b2.zip | |
core: use banker's rounding for the exact mode in flt2dec.
For the shortest mode the IEEE 754 decoder already provides an exact rounding range accounting for banker's rounding, but it was not the case for the exact mode. This commit alters the exact mode algorithm for Dragon so that any number ending at `...x5000...` with even `x` and infinite zeroes will round to `...x` instead of `...(x+1)` as it was. Grisu is not affected by this change because this halfway case always results in the failure for Grisu.
Diffstat (limited to 'src/libcore/num')
| -rw-r--r-- | src/libcore/num/flt2dec/strategy/dragon.rs | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/libcore/num/flt2dec/strategy/dragon.rs b/src/libcore/num/flt2dec/strategy/dragon.rs index bd735594e82..a819932525b 100644 --- a/src/libcore/num/flt2dec/strategy/dragon.rs +++ b/src/libcore/num/flt2dec/strategy/dragon.rs @@ -307,7 +307,11 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi } // rounding up if we stop in the middle of digits - if mant >= *scale.mul_small(5) { + // if the following digits are exactly 5000..., check the prior digit and try to + // round to even (i.e. avoid rounding up when the prior digit is even). + let order = mant.cmp(scale.mul_small(5)); + if order == Ordering::Greater || (order == Ordering::Equal && + (len == 0 || buf[len-1] & 1 == 1)) { // if rounding up changes the length, the exponent should also change. // but we've been requested a fixed number of digits, so do not alter the buffer... if let Some(c) = round_up(buf, len) { |
