core: fixed a slight bug.

The bug involves the incorrect logic for `core::num::flt2dec::decoder`.
This makes some numbers in the form of 2^n missing one final digits,
which breaks the bijectivity criterion. The regression tests have been
added, and f32 exhaustive test is rerun to get the updated result.
This commit is contained in:
Kang Seonghoon 2015-04-21 20:32:25 +09:00
parent 8a195f0754
commit 97ea7c14ba
3 changed files with 23 additions and 9 deletions

View file

@ -75,7 +75,7 @@ pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) {
FpCategory::Infinite => FullDecoded::Infinite,
FpCategory::Zero => FullDecoded::Zero,
FpCategory::Subnormal => {
// (mant - 2, exp) -- (mant, exp) -- (mant + 2, exp)
// neighbors: (mant - 2, exp) -- (mant, exp) -- (mant + 2, exp)
// Float::integer_decode always preserves the exponent,
// so the mantissa is scaled for subnormals.
FullDecoded::Finite(Decoded { mant: mant, minus: 1, plus: 1,
@ -83,13 +83,13 @@ pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) {
}
FpCategory::Normal => {
let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode();
if mant == minnorm.0 && exp == minnorm.1 {
// (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp)
if mant == minnorm.0 {
// neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp)
// where maxmant = minnormmant * 2 - 1
FullDecoded::Finite(Decoded { mant: mant << 1, minus: 1, plus: 2,
exp: exp - 1, inclusive: even })
FullDecoded::Finite(Decoded { mant: mant << 2, minus: 1, plus: 2,
exp: exp - 2, inclusive: even })
} else {
// (mant - 1, exp) -- (mant, exp) -- (mant + 1, exp)
// neighbors: (mant - 1, exp) -- (mant, exp) -- (mant + 1, exp)
FullDecoded::Finite(Decoded { mant: mant << 1, minus: 1, plus: 1,
exp: exp - 1, inclusive: even })
}