diff options
| author | bors <bors@rust-lang.org> | 2019-11-27 12:16:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-27 12:16:52 +0000 |
| commit | 04e69e4f4234beb4f12cc76dcc53e2cc4247a9be (patch) | |
| tree | 148834cf05a0062cc851f578c636241d0bd87b30 /src/libcore/num | |
| parent | 876a72a251e0d533f776fa9149b3e4daaeea3a61 (diff) | |
| parent | 166471e7f1f05fe272a4df99c20c1ffc0204a25f (diff) | |
| download | rust-04e69e4f4234beb4f12cc76dcc53e2cc4247a9be.tar.gz rust-04e69e4f4234beb4f12cc76dcc53e2cc4247a9be.zip | |
Auto merge of #66691 - dtolnay:fmt0, r=sfackler
Format libcore with rustfmt I am interested in whether we can begin cautious incremental progress on #66688 and assess along the way whether we can keep the disruption sufficiently small. This PR applies rustfmt with default settings to files in src/libcore *that are not involved in any currently open PR* to minimize merge conflicts. The list of files involved in open PRs was determined by querying GitHub's GraphQL API [with this script](https://gist.github.com/dtolnay/aa9c34993dc051a4f344d1b10e4487e8). With the list of files from the script in `outstanding_files`, the relevant commands were: ```console $ find src/libcore -name '*.rs' | xargs rustfmt --edition=2018 $ rg libcore outstanding_files | xargs git checkout -- ``` Repeating this process several months apart should get us coverage of most of the rest of libcore.
Diffstat (limited to 'src/libcore/num')
| -rw-r--r-- | src/libcore/num/bignum.rs | 56 | ||||
| -rw-r--r-- | src/libcore/num/dec2flt/algorithm.rs | 14 | ||||
| -rw-r--r-- | src/libcore/num/dec2flt/mod.rs | 36 | ||||
| -rw-r--r-- | src/libcore/num/dec2flt/num.rs | 14 | ||||
| -rw-r--r-- | src/libcore/num/dec2flt/parse.rs | 2 | ||||
| -rw-r--r-- | src/libcore/num/dec2flt/rawfp.rs | 70 | ||||
| -rw-r--r-- | src/libcore/num/diy_float.rs | 13 | ||||
| -rw-r--r-- | src/libcore/num/flt2dec/decoder.rs | 33 | ||||
| -rw-r--r-- | src/libcore/num/flt2dec/mod.rs | 196 | ||||
| -rw-r--r-- | src/libcore/num/flt2dec/strategy/dragon.rs | 143 | ||||
| -rw-r--r-- | src/libcore/num/flt2dec/strategy/grisu.rs | 292 | ||||
| -rw-r--r-- | src/libcore/num/wrapping.rs | 16 |
12 files changed, 551 insertions, 334 deletions
diff --git a/src/libcore/num/bignum.rs b/src/libcore/num/bignum.rs index 342ac69748d..b8ddd5322a1 100644 --- a/src/libcore/num/bignum.rs +++ b/src/libcore/num/bignum.rs @@ -12,13 +12,15 @@ // This module is only for dec2flt and flt2dec, and only public because of coretests. // It is not intended to ever be stabilized. #![doc(hidden)] -#![unstable(feature = "core_private_bignum", - reason = "internal routines only exposed for testing", - issue = "0")] +#![unstable( + feature = "core_private_bignum", + reason = "internal routines only exposed for testing", + issue = "0" +)] #![macro_use] -use crate::mem; use crate::intrinsics; +use crate::mem; /// Arithmetic operations required by bignums. pub trait FullOps: Sized { @@ -36,10 +38,8 @@ pub trait FullOps: Sized { /// Returns `(quo, rem)` such that `borrow * 2^W + self = quo * other + rem` /// and `0 <= rem < other`, where `W` is the number of bits in `Self`. - fn full_div_rem(self, - other: Self, - borrow: Self) - -> (Self /* quotient */, Self /* remainder */); + fn full_div_rem(self, other: Self, borrow: Self) + -> (Self /* quotient */, Self /* remainder */); } macro_rules! impl_full_ops { @@ -98,7 +98,7 @@ impl_full_ops! { const SMALL_POW5: [(u64, usize); 3] = [(125, 3), (15625, 6), (1_220_703_125, 13)]; macro_rules! define_bignum { - ($name:ident: type=$ty:ty, n=$n:expr) => ( + ($name:ident: type=$ty:ty, n=$n:expr) => { /// Stack-allocated arbitrary-precision (up to certain limit) integer. /// /// This is backed by a fixed-size array of given type ("digit"). @@ -115,7 +115,7 @@ macro_rules! define_bignum { size: usize, /// Digits. `[a, b, c, ...]` represents `a + b*2^W + c*2^(2W) + ...` /// where `W` is the number of bits in the digit type. - base: [$ty; $n] + base: [$ty; $n], } impl $name { @@ -180,7 +180,7 @@ macro_rules! define_bignum { } // This could be optimized with leading_zeros() and bit shifts, but that's // probably not worth the hassle. - let digitbits = mem::size_of::<$ty>()* 8; + let digitbits = mem::size_of::<$ty>() * 8; let mut i = nonzero.len() * digitbits - 1; while self.get_bit(i) == 0 { i -= 1; @@ -272,12 +272,12 @@ macro_rules! define_bignum { let bits = bits % digitbits; assert!(digits < $n); - debug_assert!(self.base[$n-digits..].iter().all(|&v| v == 0)); - debug_assert!(bits == 0 || (self.base[$n-digits-1] >> (digitbits - bits)) == 0); + debug_assert!(self.base[$n - digits..].iter().all(|&v| v == 0)); + debug_assert!(bits == 0 || (self.base[$n - digits - 1] >> (digitbits - bits)) == 0); // shift by `digits * digitbits` bits for i in (0..self.size).rev() { - self.base[i+digits] = self.base[i]; + self.base[i + digits] = self.base[i]; } for i in 0..digits { self.base[i] = 0; @@ -287,14 +287,14 @@ macro_rules! define_bignum { let mut sz = self.size + digits; if bits > 0 { let last = sz; - let overflow = self.base[last-1] >> (digitbits - bits); + let overflow = self.base[last - 1] >> (digitbits - bits); if overflow > 0 { self.base[last] = overflow; sz += 1; } - for i in (digits+1..last).rev() { - self.base[i] = (self.base[i] << bits) | - (self.base[i-1] >> (digitbits - bits)); + for i in (digits + 1..last).rev() { + self.base[i] = + (self.base[i] << bits) | (self.base[i - 1] >> (digitbits - bits)); } self.base[digits] <<= bits; // self.base[..digits] is zero, no need to shift @@ -331,7 +331,6 @@ macro_rules! define_bignum { self } - /// Multiplies itself by a number described by `other[0] + other[1] * 2^W + /// other[2] * 2^(2W) + ...` (where `W` is the number of bits in the digit type) /// and returns its own mutable reference. @@ -342,7 +341,9 @@ macro_rules! define_bignum { let mut retsz = 0; for (i, &a) in aa.iter().enumerate() { - if a == 0 { continue; } + if a == 0 { + continue; + } let mut sz = bb.len(); let mut carry = 0; for (j, &b) in bb.iter().enumerate() { @@ -430,11 +431,12 @@ macro_rules! define_bignum { } impl crate::cmp::PartialEq for $name { - fn eq(&self, other: &$name) -> bool { self.base[..] == other.base[..] } + fn eq(&self, other: &$name) -> bool { + self.base[..] == other.base[..] + } } - impl crate::cmp::Eq for $name { - } + impl crate::cmp::Eq for $name {} impl crate::cmp::PartialOrd for $name { fn partial_cmp(&self, other: &$name) -> crate::option::Option<crate::cmp::Ordering> { @@ -462,17 +464,17 @@ macro_rules! define_bignum { fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { use crate::mem; - let sz = if self.size < 1 {1} else {self.size}; + let sz = if self.size < 1 { 1 } else { self.size }; let digitlen = mem::size_of::<$ty>() * 2; - write!(f, "{:#x}", self.base[sz-1])?; - for &v in self.base[..sz-1].iter().rev() { + write!(f, "{:#x}", self.base[sz - 1])?; + for &v in self.base[..sz - 1].iter().rev() { write!(f, "_{:01$x}", v, digitlen)?; } crate::result::Result::Ok(()) } } - ) + }; } /// The digit type for `Big32x40`. diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs index 64146302626..c5f6903f379 100644 --- a/src/libcore/num/dec2flt/algorithm.rs +++ b/src/libcore/num/dec2flt/algorithm.rs @@ -1,11 +1,11 @@ //! The various algorithms from the paper. use crate::cmp::min; -use crate::cmp::Ordering::{Less, Equal, Greater}; -use crate::num::diy_float::Fp; -use crate::num::dec2flt::table; -use crate::num::dec2flt::rawfp::{self, Unpacked, RawFloat, fp_to_float, next_float, prev_float}; +use crate::cmp::Ordering::{Equal, Greater, Less}; use crate::num::dec2flt::num::{self, Big}; +use crate::num::dec2flt::rawfp::{self, fp_to_float, next_float, prev_float, RawFloat, Unpacked}; +use crate::num::dec2flt::table; +use crate::num::diy_float::Fp; /// Number of significand bits in Fp const P: u32 = 64; @@ -23,9 +23,9 @@ fn power_of_ten(e: i16) -> Fp { // In most architectures, floating point operations have an explicit bit size, therefore the // precision of the computation is determined on a per-operation basis. -#[cfg(any(not(target_arch="x86"), target_feature="sse2"))] +#[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))] mod fpu_precision { - pub fn set_precision<T>() { } + pub fn set_precision<T>() {} } // On x86, the x87 FPU is used for float operations if the SSE/SSE2 extensions are not available. @@ -33,7 +33,7 @@ mod fpu_precision { // round to 80 bits causing double rounding to happen when values are eventually represented as // 32/64 bit float values. To overcome this, the FPU control word can be set so that the // computations are performed in the desired precision. -#[cfg(all(target_arch="x86", not(target_feature="sse2")))] +#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] mod fpu_precision { use crate::mem::size_of; diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 4536bbc94ad..6fe9af8cbd8 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -78,23 +78,25 @@ //! turned into {positive,negative} {zero,infinity}. #![doc(hidden)] -#![unstable(feature = "dec2flt", - reason = "internal routines only exposed for testing", - issue = "0")] +#![unstable( + feature = "dec2flt", + reason = "internal routines only exposed for testing", + issue = "0" +)] use crate::fmt; use crate::str::FromStr; -use self::parse::{parse_decimal, Decimal, Sign, ParseResult}; use self::num::digits_to_big; +use self::parse::{parse_decimal, Decimal, ParseResult, Sign}; use self::rawfp::RawFloat; mod algorithm; -mod table; mod num; +mod table; // These two have their own tests. -pub mod rawfp; pub mod parse; +pub mod rawfp; macro_rules! from_str_float_impl { ($t:ty) => { @@ -155,7 +157,7 @@ macro_rules! from_str_float_impl { dec2flt(src) } } - } + }; } from_str_float_impl!(f32); from_str_float_impl!(f64); @@ -171,7 +173,7 @@ from_str_float_impl!(f64); #[derive(Debug, Clone, PartialEq, Eq)] #[stable(feature = "rust1", since = "1.0.0")] pub struct ParseFloatError { - kind: FloatErrorKind + kind: FloatErrorKind, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -181,10 +183,12 @@ enum FloatErrorKind { } impl ParseFloatError { - #[unstable(feature = "int_error_internals", - reason = "available through Error trait and this method should \ - not be exposed publicly", - issue = "0")] + #[unstable( + feature = "int_error_internals", + reason = "available through Error trait and this method should \ + not be exposed publicly", + issue = "0" + )] #[doc(hidden)] pub fn __description(&self) -> &str { match self.kind { @@ -222,7 +226,7 @@ fn extract_sign(s: &str) -> (Sign, &str) { /// Converts a decimal string into a floating point number. fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> { if s.is_empty() { - return Err(pfe_empty()) + return Err(pfe_empty()); } let (sign, s) = extract_sign(s); let flt = match parse_decimal(s) { @@ -232,8 +236,10 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> { ParseResult::Invalid => match s { "inf" => T::INFINITY, "NaN" => T::NAN, - _ => { return Err(pfe_invalid()); } - } + _ => { + return Err(pfe_invalid()); + } + }, }; match sign { diff --git a/src/libcore/num/dec2flt/num.rs b/src/libcore/num/dec2flt/num.rs index 4d50516ce54..208783dd32f 100644 --- a/src/libcore/num/dec2flt/num.rs +++ b/src/libcore/num/dec2flt/num.rs @@ -2,7 +2,7 @@ // FIXME This module's name is a bit unfortunate, since other modules also import `core::num`. -use crate::cmp::Ordering::{self, Less, Equal, Greater}; +use crate::cmp::Ordering::{self, Equal, Greater, Less}; pub use crate::num::bignum::Big32x40 as Big; @@ -36,7 +36,10 @@ pub fn compare_with_half_ulp(f: &Big, ones_place: usize) -> Ordering { /// 1. using `FromStr` on `&[u8]` requires `from_utf8_unchecked`, which is bad, and /// 2. piecing together the results of `integral.parse()` and `fractional.parse()` is /// more complicated than this entire function. -pub fn from_str_unchecked<'a, T>(bytes: T) -> u64 where T : IntoIterator<Item=&'a u8> { +pub fn from_str_unchecked<'a, T>(bytes: T) -> u64 +where + T: IntoIterator<Item = &'a u8>, +{ let mut result = 0; for &c in bytes { result = result * 10 + (c - b'0') as u64; @@ -61,14 +64,9 @@ pub fn digits_to_big(integral: &[u8], fractional: &[u8]) -> Big { pub fn to_u64(x: &Big) -> u64 { assert!(x.bit_length() < 64); let d = x.digits(); - if d.len() < 2 { - d[0] as u64 - } else { - (d[1] as u64) << 32 | d[0] as u64 - } + if d.len() < 2 { d[0] as u64 } else { (d[1] as u64) << 32 | d[0] as u64 } } - /// Extracts a range of bits. /// Index 0 is the least significant bit and the range is half-open as usual. diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index cf3664a8748..93b08bce853 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -10,8 +10,8 @@ //! modules rely on to not panic (or overflow) in turn. //! To make matters worse, all that happens in a single pass over the input. //! So, be careful when modifying anything, and double-check with the other modules. +use self::ParseResult::{Invalid, ShortcutToInf, ShortcutToZero, Valid}; use super::num; -use self::ParseResult::{Valid, ShortcutToInf, ShortcutToZero, Invalid}; #[derive(Debug)] pub enum Sign { diff --git a/src/libcore/num/dec2flt/rawfp.rs b/src/libcore/num/dec2flt/rawfp.rs index fdbdaa238e0..a127c6c3fa7 100644 --- a/src/libcore/num/dec2flt/rawfp.rs +++ b/src/libcore/num/dec2flt/rawfp.rs @@ -17,15 +17,15 @@ //! Many functions in this module only handle normal numbers. The dec2flt routines conservatively //! take the universally-correct slow path (Algorithm M) for very small and very large numbers. //! That algorithm needs only next_float() which does handle subnormals and zeros. -use crate::cmp::Ordering::{Less, Equal, Greater}; +use crate::cmp::Ordering::{Equal, Greater, Less}; use crate::convert::{TryFrom, TryInto}; -use crate::ops::{Add, Mul, Div, Neg}; use crate::fmt::{Debug, LowerExp}; -use crate::num::diy_float::Fp; -use crate::num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan}; -use crate::num::FpCategory; use crate::num::dec2flt::num::{self, Big}; use crate::num::dec2flt::table; +use crate::num::diy_float::Fp; +use crate::num::FpCategory; +use crate::num::FpCategory::{Infinite, Nan, Normal, Subnormal, Zero}; +use crate::ops::{Add, Div, Mul, Neg}; #[derive(Copy, Clone, Debug)] pub struct Unpacked { @@ -44,13 +44,8 @@ impl Unpacked { /// See the parent module's doc comment for why this is necessary. /// /// Should **never ever** be implemented for other types or be used outside the dec2flt module. -pub trait RawFloat - : Copy - + Debug - + LowerExp - + Mul<Output=Self> - + Div<Output=Self> - + Neg<Output=Self> +pub trait RawFloat: + Copy + Debug + LowerExp + Mul<Output = Self> + Div<Output = Self> + Neg<Output = Self> { const INFINITY: Self; const NAN: Self; @@ -144,7 +139,7 @@ macro_rules! other_constants { const INFINITY: Self = $crate::$type::INFINITY; const NAN: Self = $crate::$type::NAN; const ZERO: Self = 0.0; - } + }; } impl RawFloat for f32 { @@ -163,11 +158,8 @@ impl RawFloat for f32 { let bits = self.to_bits(); let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; - let mantissa = if exponent == 0 { - (bits & 0x7fffff) << 1 - } else { - (bits & 0x7fffff) | 0x800000 - }; + let mantissa = + if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 }; // Exponent bias + mantissa shift exponent -= 127 + 23; (mantissa as u64, exponent, sign) @@ -188,12 +180,17 @@ impl RawFloat for f32 { table::F32_SHORT_POWERS[e] } - fn classify(self) -> FpCategory { self.classify() } - fn to_bits(self) -> Self::Bits { self.to_bits() } - fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) } + fn classify(self) -> FpCategory { + self.classify() + } + fn to_bits(self) -> Self::Bits { + self.to_bits() + } + fn from_bits(v: Self::Bits) -> Self { + Self::from_bits(v) + } } - impl RawFloat for f64 { type Bits = u64; @@ -235,9 +232,15 @@ impl RawFloat for f64 { table::F64_SHORT_POWERS[e] } - fn classify(self) -> FpCategory { self.classify() } - fn to_bits(self) -> Self::Bits { self.to_bits() } - fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) } + fn classify(self) -> FpCategory { + self.classify() + } + fn to_bits(self) -> Self::Bits { + self.to_bits() + } + fn from_bits(v: Self::Bits) -> Self { + Self::from_bits(v) + } } /// Converts an `Fp` to the closest machine float type. @@ -248,7 +251,7 @@ pub fn fp_to_float<T: RawFloat>(x: Fp) -> T { let e = x.e + 63; if e > T::MAX_EXP { panic!("fp_to_float: exponent {} too large", e) - } else if e > T::MIN_EXP { + } else if e > T::MIN_EXP { encode_normal(round_normal::<T>(x)) } else { panic!("fp_to_float: exponent {} too small", e) @@ -278,14 +281,15 @@ pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked { /// Inverse of `RawFloat::unpack()` for normalized numbers. /// Panics if the significand or exponent are not valid for normalized numbers. pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T { - debug_assert!(T::MIN_SIG <= x.sig && x.sig <= T::MAX_SIG, - "encode_normal: significand not normalized"); + debug_assert!( + T::MIN_SIG <= x.sig && x.sig <= T::MAX_SIG, + "encode_normal: significand not normalized" + ); // Remove the hidden bit let sig_enc = x.sig & !(1 << T::EXPLICIT_SIG_BITS); // Adjust the exponent for exponent bias and mantissa shift let k_enc = x.k + T::MAX_EXP + T::EXPLICIT_SIG_BITS as i16; - debug_assert!(k_enc != 0 && k_enc < T::MAX_ENCODED_EXP, - "encode_normal: exponent out of range"); + debug_assert!(k_enc != 0 && k_enc < T::MAX_ENCODED_EXP, "encode_normal: exponent out of range"); // Leave sign bit at 0 ("+"), our numbers are all positive let bits = (k_enc as u64) << T::EXPLICIT_SIG_BITS | sig_enc; T::from_bits(bits.try_into().unwrap_or_else(|_| unreachable!())) @@ -315,7 +319,7 @@ pub fn big_to_fp(f: &Big) -> Fp { Equal | Greater => match leading.checked_add(1) { Some(f) => Fp { f, e }.normalize(), None => Fp { f: 1 << 63, e: e + 1 }, - } + }, } } @@ -354,8 +358,6 @@ pub fn next_float<T: RawFloat>(x: T) -> T { // want, and the mantissa bits become zero. Because of the hidden bit convention, this // too is exactly what we want! // Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY. - Zero | Subnormal | Normal => { - T::from_bits(x.to_bits() + T::Bits::from(1u8)) - } + Zero | Subnormal | Normal => T::from_bits(x.to_bits() + T::Bits::from(1u8)), } } diff --git a/src/libcore/num/diy_float.rs b/src/libcore/num/diy_float.rs index cdf33298949..0e601d45a21 100644 --- a/src/libcore/num/diy_float.rs +++ b/src/libcore/num/diy_float.rs @@ -3,9 +3,11 @@ // This module is only for dec2flt and flt2dec, and only public because of coretests. // It is not intended to ever be stabilized. #![doc(hidden)] -#![unstable(feature = "core_private_diy_float", - reason = "internal routines only exposed for testing", - issue = "0")] +#![unstable( + feature = "core_private_diy_float", + reason = "internal routines only exposed for testing", + issue = "0" +)] /// A custom 64-bit floating point type, representing `f * 2^e`. #[derive(Copy, Clone, Debug)] @@ -74,9 +76,6 @@ impl Fp { assert!(edelta >= 0); let edelta = edelta as usize; assert_eq!(self.f << edelta >> edelta, self.f); - Fp { - f: self.f << edelta, - e, - } + Fp { f: self.f << edelta, e } } } diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index ee0f18ba295..2b74effbe2e 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -1,8 +1,8 @@ //! Decodes a floating-point value into individual parts and error ranges. -use crate::{f32, f64}; -use crate::num::FpCategory; use crate::num::dec2flt::rawfp::RawFloat; +use crate::num::FpCategory; +use crate::{f32, f64}; /// Decoded unsigned finite value, such that: /// @@ -47,11 +47,15 @@ pub trait DecodableFloat: RawFloat + Copy { } impl DecodableFloat for f32 { - fn min_pos_norm_value() -> Self { f32::MIN_POSITIVE } + fn min_pos_norm_value() -> Self { + f32::MIN_POSITIVE + } } impl DecodableFloat for f64 { - fn min_pos_norm_value() -> Self { f64::MIN_POSITIVE } + fn min_pos_norm_value() -> Self { + f64::MIN_POSITIVE + } } /// Returns a sign (true when negative) and `FullDecoded` value @@ -67,20 +71,29 @@ pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) { // 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, minus: 1, plus: 1, - exp, inclusive: even }) + FullDecoded::Finite(Decoded { mant, minus: 1, plus: 1, exp, inclusive: even }) } FpCategory::Normal => { let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode(); if mant == minnorm.0 { // neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp) // where maxmant = minnormmant * 2 - 1 - FullDecoded::Finite(Decoded { mant: mant << 2, minus: 1, plus: 2, - exp: exp - 2, inclusive: even }) + FullDecoded::Finite(Decoded { + mant: mant << 2, + minus: 1, + plus: 2, + exp: exp - 2, + inclusive: even, + }) } else { // neighbors: (mant - 1, exp) -- (mant, exp) -- (mant + 1, exp) - FullDecoded::Finite(Decoded { mant: mant << 1, minus: 1, plus: 1, - exp: exp - 1, inclusive: even }) + FullDecoded::Finite(Decoded { + mant: mant << 1, + minus: 1, + plus: 1, + exp: exp - 1, + inclusive: even, + }) } } }; diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index 6d42a777449..63df5613453 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -116,15 +116,17 @@ functions. // while this is extensively documented, this is in principle private which is // only made public for testing. do not expose us. #![doc(hidden)] -#![unstable(feature = "flt2dec", - reason = "internal routines only exposed for testing", - issue = "0")] +#![unstable( + feature = "flt2dec", + reason = "internal routines only exposed for testing", + issue = "0" +)] +pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded}; use crate::i16; -pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded}; -pub mod estimator; pub mod decoder; +pub mod estimator; /// Digit-generation algorithms. pub mod strategy { @@ -144,17 +146,24 @@ pub const MAX_SIG_DIGITS: usize = 17; #[doc(hidden)] pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> { match d[..n].iter().rposition(|&c| c != b'9') { - Some(i) => { // d[i+1..n] is all nines + Some(i) => { + // d[i+1..n] is all nines d[i] += 1; - for j in i+1..n { d[j] = b'0'; } + for j in i + 1..n { + d[j] = b'0'; + } None } - None if n > 0 => { // 999..999 rounds to 1000..000 with an increased exponent + None if n > 0 => { + // 999..999 rounds to 1000..000 with an increased exponent d[0] = b'1'; - for j in 1..n { d[j] = b'0'; } + for j in 1..n { + d[j] = b'0'; + } Some(b'0') } - None => { // an empty buffer rounds up (a bit strange but reasonable) + None => { + // an empty buffer rounds up (a bit strange but reasonable) Some(b'1') } } @@ -176,8 +185,19 @@ impl<'a> Part<'a> { pub fn len(&self) -> usize { match *self { Part::Zero(nzeroes) => nzeroes, - Part::Num(v) => if v < 1_000 { if v < 10 { 1 } else if v < 100 { 2 } else { 3 } } - else { if v < 10_000 { 4 } else { 5 } }, + Part::Num(v) => { + if v < 1_000 { + if v < 10 { + 1 + } else if v < 100 { + 2 + } else { + 3 + } + } else { + if v < 10_000 { 4 } else { 5 } + } + } Part::Copy(buf) => buf.len(), } } @@ -190,7 +210,9 @@ impl<'a> Part<'a> { if out.len() >= len { match *self { Part::Zero(nzeroes) => { - for c in &mut out[..nzeroes] { *c = b'0'; } + for c in &mut out[..nzeroes] { + *c = b'0'; + } } Part::Num(mut v) => { for c in out[..len].iter_mut().rev() { @@ -234,7 +256,9 @@ impl<'a> Formatted<'a> { /// Returns the number of written bytes, or `None` if the buffer is not enough. /// (It may still leave partially written bytes in the buffer; do not rely on that.) pub fn write(&self, out: &mut [u8]) -> Option<usize> { - if out.len() < self.sign.len() { return None; } + if out.len() < self.sign.len() { + return None; + } out[..self.sign.len()].copy_from_slice(self.sign); let mut written = self.sign.len(); @@ -254,8 +278,12 @@ impl<'a> Formatted<'a> { /// it will be ignored and full digits will be printed. It is only used to print /// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that /// it will only print given digits and nothing else. -fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize, - parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { +fn digits_to_dec_str<'a>( + buf: &'a [u8], + exp: i16, + frac_digits: usize, + parts: &'a mut [Part<'a>], +) -> &'a [Part<'a>] { assert!(!buf.is_empty()); assert!(buf[0] > b'0'); assert!(parts.len() >= 4); @@ -322,8 +350,13 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize, /// it will be ignored and full digits will be printed. It is only used to print /// additional zeroes after rendered digits. Thus, `min_digits == 0` means that /// it will only print the given digits and nothing else. -fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool, - parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { +fn digits_to_exp_str<'a>( + buf: &'a [u8], + exp: i16, + min_ndigits: usize, + upper: bool, + parts: &'a mut [Part<'a>], +) -> &'a [Part<'a>] { assert!(!buf.is_empty()); assert!(buf[0] > b'0'); assert!(parts.len() >= 6); @@ -359,11 +392,11 @@ fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: boo #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Sign { /// Prints `-` only for the negative non-zero values. - Minus, // -inf -1 0 0 1 inf nan + Minus, // -inf -1 0 0 1 inf nan /// Prints `-` only for any negative values (including the negative zero). - MinusRaw, // -inf -1 -0 0 1 inf nan + MinusRaw, // -inf -1 -0 0 1 inf nan /// Prints `-` for the negative non-zero values, or `+` otherwise. - MinusPlus, // -inf -1 +0 +0 +1 +inf nan + MinusPlus, // -inf -1 +0 +0 +1 +inf nan /// Prints `-` for any negative values (including the negative zero), or `+` otherwise. MinusPlusRaw, // -inf -1 -0 +0 +1 +inf nan } @@ -374,11 +407,35 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static match (*decoded, sign) { (FullDecoded::Nan, _) => b"", (FullDecoded::Zero, Sign::Minus) => b"", - (FullDecoded::Zero, Sign::MinusRaw) => if negative { b"-" } else { b"" }, + (FullDecoded::Zero, Sign::MinusRaw) => { + if negative { + b"-" + } else { + b"" + } + } (FullDecoded::Zero, Sign::MinusPlus) => b"+", - (FullDecoded::Zero, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" }, - (_, Sign::Minus) | (_, Sign::MinusRaw) => if negative { b"-" } else { b"" }, - (_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" }, + (FullDecoded::Zero, Sign::MinusPlusRaw) => { + if negative { + b"-" + } else { + b"+" + } + } + (_, Sign::Minus) | (_, Sign::MinusRaw) => { + if negative { + b"-" + } else { + b"" + } + } + (_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => { + if negative { + b"-" + } else { + b"+" + } + } } } @@ -400,10 +457,19 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static /// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. /// There should be at least 4 parts available, due to the worst case like /// `[+][0.][0000][2][0000]` with `frac_digits = 10`. -pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, - sign: Sign, frac_digits: usize, _upper: bool, - buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { +pub fn to_shortest_str<'a, T, F>( + mut format_shortest: F, + v: T, + sign: Sign, + frac_digits: usize, + _upper: bool, + buf: &'a mut [u8], + parts: &'a mut [Part<'a>], +) -> Formatted<'a> +where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), +{ assert!(parts.len() >= 4); assert!(buf.len() >= MAX_SIG_DIGITS); @@ -419,7 +485,8 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, Formatted { sign, parts: &parts[..1] } } FullDecoded::Zero => { - if frac_digits > 0 { // [0.][0000] + if frac_digits > 0 { + // [0.][0000] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(frac_digits); Formatted { sign, parts: &parts[..2] } @@ -430,8 +497,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, } FullDecoded::Finite(ref decoded) => { let (len, exp) = format_shortest(decoded, buf); - Formatted { sign, - parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } + Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } } } } @@ -455,10 +521,19 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, /// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. /// There should be at least 6 parts available, due to the worst case like /// `[+][1][.][2345][e][-][6]`. -pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, - sign: Sign, dec_bounds: (i16, i16), upper: bool, - buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { +pub fn to_shortest_exp_str<'a, T, F>( + mut format_shortest: F, + v: T, + sign: Sign, + dec_bounds: (i16, i16), + upper: bool, + buf: &'a mut [u8], + parts: &'a mut [Part<'a>], +) -> Formatted<'a> +where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), +{ assert!(parts.len() >= 6); assert!(buf.len() >= MAX_SIG_DIGITS); assert!(dec_bounds.0 <= dec_bounds.1); @@ -534,10 +609,19 @@ fn estimate_max_buf_len(exp: i16) -> usize { /// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.) /// There should be at least 6 parts available, due to the worst case like /// `[+][1][.][2345][e][-][6]`. -pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, - sign: Sign, ndigits: usize, upper: bool, - buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +pub fn to_exact_exp_str<'a, T, F>( + mut format_exact: F, + v: T, + sign: Sign, + ndigits: usize, + upper: bool, + buf: &'a mut [u8], + parts: &'a mut [Part<'a>], +) -> Formatted<'a> +where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ assert!(parts.len() >= 6); assert!(ndigits > 0); @@ -553,7 +637,8 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, Formatted { sign, parts: &parts[..1] } } FullDecoded::Zero => { - if ndigits > 1 { // [0.][0000][e0] + if ndigits > 1 { + // [0.][0000][e0] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(ndigits - 1); parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" }); @@ -569,8 +654,7 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, let trunc = if ndigits < maxlen { ndigits } else { maxlen }; let (len, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN); - Formatted { sign, - parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) } + Formatted { sign, parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) } } } } @@ -590,10 +674,19 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, /// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.) /// There should be at least 4 parts available, due to the worst case like /// `[+][0.][0000][2][0000]` with `frac_digits = 10`. -pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, - sign: Sign, frac_digits: usize, _upper: bool, - buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +pub fn to_exact_fixed_str<'a, T, F>( + mut format_exact: F, + v: T, + sign: Sign, + frac_digits: usize, + _upper: bool, + buf: &'a mut [u8], + parts: &'a mut [Part<'a>], +) -> Formatted<'a> +where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ assert!(parts.len() >= 4); let (negative, full_decoded) = decode(v); @@ -608,7 +701,8 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, Formatted { sign, parts: &parts[..1] } } FullDecoded::Zero => { - if frac_digits > 0 { // [0.][0000] + if frac_digits > 0 { + // [0.][0000] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(frac_digits); Formatted { sign, parts: &parts[..2] } @@ -631,7 +725,8 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, // `exp` was. this does not include the case that the restriction has been met // only after the final rounding-up; it's a regular case with `exp = limit + 1`. debug_assert_eq!(len, 0); - if frac_digits > 0 { // [0.][0000] + if frac_digits > 0 { + // [0.][0000] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(frac_digits); Formatted { sign, parts: &parts[..2] } @@ -640,8 +735,7 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, Formatted { sign, parts: &parts[..1] } } } else { - Formatted { sign, - parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } + Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } } } } diff --git a/src/libcore/num/flt2dec/strategy/dragon.rs b/src/libcore/num/flt2dec/strategy/dragon.rs index 35fb4b92758..c8de0004352 100644 --- a/src/libcore/num/flt2dec/strategy/dragon.rs +++ b/src/libcore/num/flt2dec/strategy/dragon.rs @@ -6,38 +6,54 @@ use crate::cmp::Ordering; -use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up}; -use crate::num::flt2dec::estimator::estimate_scaling_factor; -use crate::num::bignum::Digit32 as Digit; use crate::num::bignum::Big32x40 as Big; +use crate::num::bignum::Digit32 as Digit; +use crate::num::flt2dec::estimator::estimate_scaling_factor; +use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS}; -static POW10: [Digit; 10] = [1, 10, 100, 1000, 10000, 100000, - 1000000, 10000000, 100000000, 1000000000]; -static TWOPOW10: [Digit; 10] = [2, 20, 200, 2000, 20000, 200000, - 2000000, 20000000, 200000000, 2000000000]; +static POW10: [Digit; 10] = + [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]; +static TWOPOW10: [Digit; 10] = + [2, 20, 200, 2000, 20000, 200000, 2000000, 20000000, 200000000, 2000000000]; // precalculated arrays of `Digit`s for 10^(2^n) static POW10TO16: [Digit; 2] = [0x6fc10000, 0x2386f2]; static POW10TO32: [Digit; 4] = [0, 0x85acef81, 0x2d6d415b, 0x4ee]; static POW10TO64: [Digit; 7] = [0, 0, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x184f03]; -static POW10TO128: [Digit; 14] = - [0, 0, 0, 0, 0x2e953e01, 0x3df9909, 0xf1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, - 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x24e]; -static POW10TO256: [Digit; 27] = - [0, 0, 0, 0, 0, 0, 0, 0, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, - 0xcf4a6e70, 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, - 0xcc5573c0, 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x553f7]; +static POW10TO128: [Digit; 14] = [ + 0, 0, 0, 0, 0x2e953e01, 0x3df9909, 0xf1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, + 0xa6337f19, 0xe91f2603, 0x24e, +]; +static POW10TO256: [Digit; 27] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70, + 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, 0x65f9ef17, + 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x553f7, +]; #[doc(hidden)] pub fn mul_pow10(x: &mut Big, n: usize) -> &mut Big { debug_assert!(n < 512); - if n & 7 != 0 { x.mul_small(POW10[n & 7]); } - if n & 8 != 0 { x.mul_small(POW10[8]); } - if n & 16 != 0 { x.mul_digits(&POW10TO16); } - if n & 32 != 0 { x.mul_digits(&POW10TO32); } - if n & 64 != 0 { x.mul_digits(&POW10TO64); } - if n & 128 != 0 { x.mul_digits(&POW10TO128); } - if n & 256 != 0 { x.mul_digits(&POW10TO256); } + if n & 7 != 0 { + x.mul_small(POW10[n & 7]); + } + if n & 8 != 0 { + x.mul_small(POW10[8]); + } + if n & 16 != 0 { + x.mul_digits(&POW10TO16); + } + if n & 32 != 0 { + x.mul_digits(&POW10TO32); + } + if n & 64 != 0 { + x.mul_digits(&POW10TO64); + } + if n & 128 != 0 { + x.mul_digits(&POW10TO128); + } + if n & 256 != 0 { + x.mul_digits(&POW10TO256); + } x } @@ -52,13 +68,30 @@ fn div_2pow10(x: &mut Big, mut n: usize) -> &mut Big { } // only usable when `x < 16 * scale`; `scaleN` should be `scale.mul_small(N)` -fn div_rem_upto_16<'a>(x: &'a mut Big, scale: &Big, - scale2: &Big, scale4: &Big, scale8: &Big) -> (u8, &'a mut Big) { +fn div_rem_upto_16<'a>( + x: &'a mut Big, + scale: &Big, + scale2: &Big, + scale4: &Big, + scale8: &Big, +) -> (u8, &'a mut Big) { let mut d = 0; - if *x >= *scale8 { x.sub(scale8); d += 8; } - if *x >= *scale4 { x.sub(scale4); d += 4; } - if *x >= *scale2 { x.sub(scale2); d += 2; } - if *x >= *scale { x.sub(scale); d += 1; } + if *x >= *scale8 { + x.sub(scale8); + d += 8; + } + if *x >= *scale4 { + x.sub(scale4); + d += 4; + } + if *x >= *scale2 { + x.sub(scale2); + d += 2; + } + if *x >= *scale { + x.sub(scale); + d += 1; + } debug_assert!(*x < *scale); (d, x) } @@ -85,7 +118,7 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp assert!(buf.len() >= MAX_SIG_DIGITS); // `a.cmp(&b) < rounding` is `if d.inclusive {a <= b} else {a < b}` - let rounding = if d.inclusive {Ordering::Greater} else {Ordering::Equal}; + let rounding = if d.inclusive { Ordering::Greater } else { Ordering::Equal }; // estimate `k_0` from original inputs satisfying `10^(k_0-1) < high <= 10^(k_0+1)`. // the tight bound `k` satisfying `10^(k-1) < high <= 10^k` is calculated later. @@ -132,9 +165,12 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp } // cache `(2, 4, 8) * scale` for digit generation. - let mut scale2 = scale.clone(); scale2.mul_pow2(1); - let mut scale4 = scale.clone(); scale4.mul_pow2(2); - let mut scale8 = scale.clone(); scale8.mul_pow2(3); + let mut scale2 = scale.clone(); + scale2.mul_pow2(1); + let mut scale4 = scale.clone(); + scale4.mul_pow2(2); + let mut scale8 = scale.clone(); + scale8.mul_pow2(3); let mut down; let mut up; @@ -186,7 +222,9 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp // - keep generating otherwise. down = mant.cmp(&minus) < rounding; up = scale.cmp(mant.clone().add(&plus)) < rounding; - if down || up { break; } // we have the shortest representation, proceed to the rounding + if down || up { + break; + } // we have the shortest representation, proceed to the rounding // restore the invariants. // this makes the algorithm always terminating: `minus` and `plus` always increases, @@ -269,22 +307,40 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi if len > 0 { // cache `(2, 4, 8) * scale` for digit generation. // (this can be expensive, so do not calculate them when the buffer is empty.) - let mut scale2 = scale.clone(); scale2.mul_pow2(1); - let mut scale4 = scale.clone(); scale4.mul_pow2(2); - let mut scale8 = scale.clone(); scale8.mul_pow2(3); + let mut scale2 = scale.clone(); + scale2.mul_pow2(1); + let mut scale4 = scale.clone(); + scale4.mul_pow2(2); + let mut scale8 = scale.clone(); + scale8.mul_pow2(3); for i in 0..len { - if mant.is_zero() { // following digits are all zeroes, we stop here + if mant.is_zero() { + // following digits are all zeroes, we stop here // do *not* try to perform rounding! rather, fill remaining digits. - for c in &mut buf[i..len] { *c = b'0'; } + for c in &mut buf[i..len] { + *c = b'0'; + } return (len, k); } let mut d = 0; - if mant >= scale8 { mant.sub(&scale8); d += 8; } - if mant >= scale4 { mant.sub(&scale4); d += 4; } - if mant >= scale2 { mant.sub(&scale2); d += 2; } - if mant >= scale { mant.sub(&scale); d += 1; } + if mant >= scale8 { + mant.sub(&scale8); + d += 8; + } + if mant >= scale4 { + mant.sub(&scale4); + d += 4; + } + if mant >= scale2 { + mant.sub(&scale2); + d += 2; + } + if mant >= scale { + mant.sub(&scale); + d += 1; + } debug_assert!(mant < scale); debug_assert!(d < 10); buf[i] = b'0' + d; @@ -296,8 +352,9 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi // 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 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) { diff --git a/src/libcore/num/flt2dec/strategy/grisu.rs b/src/libcore/num/flt2dec/strategy/grisu.rs index 61b50ec8ca5..1e2db212dd0 100644 --- a/src/libcore/num/flt2dec/strategy/grisu.rs +++ b/src/libcore/num/flt2dec/strategy/grisu.rs @@ -6,12 +6,13 @@ //! accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243. use crate::num::diy_float::Fp; -use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up}; - +use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS}; // see the comments in `format_shortest_opt` for the rationale. -#[doc(hidden)] pub const ALPHA: i16 = -60; -#[doc(hidden)] pub const GAMMA: i16 = -32; +#[doc(hidden)] +pub const ALPHA: i16 = -60; +#[doc(hidden)] +pub const GAMMA: i16 = -32; /* # the following Python code generates this table: @@ -24,92 +25,95 @@ for i in xrange(-308, 333, 8): */ #[doc(hidden)] -pub static CACHED_POW10: [(u64, i16, i16); 81] = [ // (f, e, k) +pub static CACHED_POW10: [(u64, i16, i16); 81] = [ + // (f, e, k) (0xe61acf033d1a45df, -1087, -308), (0xab70fe17c79ac6ca, -1060, -300), (0xff77b1fcbebcdc4f, -1034, -292), (0xbe5691ef416bd60c, -1007, -284), - (0x8dd01fad907ffc3c, -980, -276), - (0xd3515c2831559a83, -954, -268), - (0x9d71ac8fada6c9b5, -927, -260), - (0xea9c227723ee8bcb, -901, -252), - (0xaecc49914078536d, -874, -244), - (0x823c12795db6ce57, -847, -236), - (0xc21094364dfb5637, -821, -228), - (0x9096ea6f3848984f, -794, -220), - (0xd77485cb25823ac7, -768, -212), - (0xa086cfcd97bf97f4, -741, -204), - (0xef340a98172aace5, -715, -196), - (0xb23867fb2a35b28e, -688, -188), - (0x84c8d4dfd2c63f3b, -661, -180), - (0xc5dd44271ad3cdba, -635, -172), - (0x936b9fcebb25c996, -608, -164), - (0xdbac6c247d62a584, -582, -156), - (0xa3ab66580d5fdaf6, -555, -148), - (0xf3e2f893dec3f126, -529, -140), - (0xb5b5ada8aaff80b8, -502, -132), - (0x87625f056c7c4a8b, -475, -124), - (0xc9bcff6034c13053, -449, -116), - (0x964e858c91ba2655, -422, -108), - (0xdff9772470297ebd, -396, -100), - (0xa6dfbd9fb8e5b88f, -369, -92), - (0xf8a95fcf88747d94, -343, -84), - (0xb94470938fa89bcf, -316, -76), - (0x8a08f0f8bf0f156b, -289, -68), - (0xcdb02555653131b6, -263, -60), - (0x993fe2c6d07b7fac, -236, -52), - (0xe45c10c42a2b3b06, -210, -44), - (0xaa242499697392d3, -183, -36), - (0xfd87b5f28300ca0e, -157, -28), - (0xbce5086492111aeb, -130, -20), - (0x8cbccc096f5088cc, -103, -12), - (0xd1b71758e219652c, -77, -4), - (0x9c40000000000000, -50, 4), - (0xe8d4a51000000000, -24, 12), - (0xad78ebc5ac620000, 3, 20), - (0x813f3978f8940984, 30, 28), - (0xc097ce7bc90715b3, 56, 36), - (0x8f7e32ce7bea5c70, 83, 44), - (0xd5d238a4abe98068, 109, 52), - (0x9f4f2726179a2245, 136, 60), - (0xed63a231d4c4fb27, 162, 68), - (0xb0de65388cc8ada8, 189, 76), - (0x83c7088e1aab65db, 216, 84), - (0xc45d1df942711d9a, 242, 92), - (0x924d692ca61be758, 269, 100), - (0xda01ee641a708dea, 295, 108), - (0xa26da3999aef774a, 322, 116), - (0xf209787bb47d6b85, 348, 124), - (0xb454e4a179dd1877, 375, 132), - (0x865b86925b9bc5c2, 402, 140), - (0xc83553c5c8965d3d, 428, 148), - (0x952ab45cfa97a0b3, 455, 156), - (0xde469fbd99a05fe3, 481, 164), - (0xa59bc234db398c25, 508, 172), - (0xf6c69a72a3989f5c, 534, 180), - (0xb7dcbf5354e9bece, 561, 188), - (0x88fcf317f22241e2, 588, 196), - (0xcc20ce9bd35c78a5, 614, 204), - (0x98165af37b2153df, 641, 212), - (0xe2a0b5dc971f303a, 667, 220), - (0xa8d9d1535ce3b396, 694, 228), - (0xfb9b7cd9a4a7443c, 720, 236), - (0xbb764c4ca7a44410, 747, 244), - (0x8bab8eefb6409c1a, 774, 252), - (0xd01fef10a657842c, 800, 260), - (0x9b10a4e5e9913129, 827, 268), - (0xe7109bfba19c0c9d, 853, 276), - (0xac2820d9623bf429, 880, 284), - (0x80444b5e7aa7cf85, 907, 292), - (0xbf21e44003acdd2d, 933, 300), - (0x8e679c2f5e44ff8f, 960, 308), - (0xd433179d9c8cb841, 986, 316), - (0x9e19db92b4e31ba9, 1013, 324), - (0xeb96bf6ebadf77d9, 1039, 332), + (0x8dd01fad907ffc3c, -980, -276), + (0xd3515c2831559a83, -954, -268), + (0x9d71ac8fada6c9b5, -927, -260), + (0xea9c227723ee8bcb, -901, -252), + (0xaecc49914078536d, -874, -244), + (0x823c12795db6ce57, -847, -236), + (0xc21094364dfb5637, -821, -228), + (0x9096ea6f3848984f, -794, -220), + (0xd77485cb25823ac7, -768, -212), + (0xa086cfcd97bf97f4, -741, -204), + (0xef340a98172aace5, -715, -196), + (0xb23867fb2a35b28e, -688, -188), + (0x84c8d4dfd2c63f3b, -661, -180), + (0xc5dd44271ad3cdba, -635, -172), + (0x936b9fcebb25c996, -608, -164), + (0xdbac6c247d62a584, -582, -156), + (0xa3ab66580d5fdaf6, -555, -148), + (0xf3e2f893dec3f126, -529, -140), + (0xb5b5ada8aaff80b8, -502, -132), + (0x87625f056c7c4a8b, -475, -124), + (0xc9bcff6034c13053, -449, -116), + (0x964e858c91ba2655, -422, -108), + (0xdff9772470297ebd, -396, -100), + (0xa6dfbd9fb8e5b88f, -369, -92), + (0xf8a95fcf88747d94, -343, -84), + (0xb94470938fa89bcf, -316, -76), + (0x8a08f0f8bf0f156b, -289, -68), + (0xcdb02555653131b6, -263, -60), + (0x993fe2c6d07b7fac, -236, -52), + (0xe45c10c42a2b3b06, -210, -44), + (0xaa242499697392d3, -183, -36), + (0xfd87b5f28300ca0e, -157, -28), + (0xbce5086492111aeb, -130, -20), + (0x8cbccc096f5088cc, -103, -12), + (0xd1b71758e219652c, -77, -4), + (0x9c40000000000000, -50, 4), + (0xe8d4a51000000000, -24, 12), + (0xad78ebc5ac620000, 3, 20), + (0x813f3978f8940984, 30, 28), + (0xc097ce7bc90715b3, 56, 36), + (0x8f7e32ce7bea5c70, 83, 44), + (0xd5d238a4abe98068, 109, 52), + (0x9f4f2726179a2245, 136, 60), + (0xed63a231d4c4fb27, 162, 68), + (0xb0de65388cc8ada8, 189, 76), + (0x83c7088e1aab65db, 216, 84), + (0xc45d1df942711d9a, 242, 92), + (0x924d692ca61be758, 269, 100), + (0xda01ee641a708dea, 295, 108), + (0xa26da3999aef774a, 322, 116), + (0xf209787bb47d6b85, 348, 124), + (0xb454e4a179dd1877, 375, 132), + (0x865b86925b9bc5c2, 402, 140), + (0xc83553c5c8965d3d, 428, 148), + (0x952ab45cfa97a0b3, 455, 156), + (0xde469fbd99a05fe3, 481, 164), + (0xa59bc234db398c25, 508, 172), + (0xf6c69a72a3989f5c, 534, 180), + (0xb7dcbf5354e9bece, 561, 188), + (0x88fcf317f22241e2, 588, 196), + (0xcc20ce9bd35c78a5, 614, 204), + (0x98165af37b2153df, 641, 212), + (0xe2a0b5dc971f303a, 667, 220), + (0xa8d9d1535ce3b396, 694, 228), + (0xfb9b7cd9a4a7443c, 720, 236), + (0xbb764c4ca7a44410, 747, 244), + (0x8bab8eefb6409c1a, 774, 252), + (0xd01fef10a657842c, 800, 260), + (0x9b10a4e5e9913129, 827, 268), + (0xe7109bfba19c0c9d, 853, 276), + (0xac2820d9623bf429, 880, 284), + (0x80444b5e7aa7cf85, 907, 292), + (0xbf21e44003acdd2d, 933, 300), + (0x8e679c2f5e44ff8f, 960, 308), + (0xd433179d9c8cb841, 986, 316), + (0x9e19db92b4e31ba9, 1013, 324), + (0xeb96bf6ebadf77d9, 1039, 332), ]; -#[doc(hidden)] pub const CACHED_POW10_FIRST_E: i16 = -1087; -#[doc(hidden)] pub const CACHED_POW10_LAST_E: i16 = 1039; +#[doc(hidden)] +pub const CACHED_POW10_FIRST_E: i16 = -1087; +#[doc(hidden)] +pub const CACHED_POW10_LAST_E: i16 = 1039; #[doc(hidden)] pub fn cached_power(alpha: i16, gamma: i16) -> (i16, Fp) { @@ -128,30 +132,39 @@ pub fn max_pow10_no_more_than(x: u32) -> (u8, u32) { debug_assert!(x > 0); const X9: u32 = 10_0000_0000; - const X8: u32 = 1_0000_0000; - const X7: u32 = 1000_0000; - const X6: u32 = 100_0000; - const X5: u32 = 10_0000; - const X4: u32 = 1_0000; - const X3: u32 = 1000; - const X2: u32 = 100; - const X1: u32 = 10; + const X8: u32 = 1_0000_0000; + const X7: u32 = 1000_0000; + const X6: u32 = 100_0000; + const X5: u32 = 10_0000; + const X4: u32 = 1_0000; + const X3: u32 = 1000; + const X2: u32 = 100; + const X1: u32 = 10; if x < X4 { - if x < X2 { if x < X1 {(0, 1)} else {(1, X1)} } - else { if x < X3 {(2, X2)} else {(3, X3)} } + if x < X2 { + if x < X1 { (0, 1) } else { (1, X1) } + } else { + if x < X3 { (2, X2) } else { (3, X3) } + } } else { - if x < X6 { if x < X5 {(4, X4)} else {(5, X5)} } - else if x < X8 { if x < X7 {(6, X6)} else {(7, X7)} } - else { if x < X9 {(8, X8)} else {(9, X9)} } + if x < X6 { + if x < X5 { (4, X4) } else { (5, X5) } + } else if x < X8 { + if x < X7 { (6, X6) } else { (7, X7) } + } else { + if x < X9 { (8, X8) } else { (9, X9) } + } } } /// The shortest mode implementation for Grisu. /// /// It returns `None` when it would return an inexact representation otherwise. -pub fn format_shortest_opt(d: &Decoded, - buf: &mut [u8]) -> Option<(/*#digits*/ usize, /*exp*/ i16)> { +pub fn format_shortest_opt( + d: &Decoded, + buf: &mut [u8], +) -> Option<(/*#digits*/ usize, /*exp*/ i16)> { assert!(d.mant > 0); assert!(d.minus > 0); assert!(d.plus > 0); @@ -208,8 +221,8 @@ pub fn format_shortest_opt(d: &Decoded, // we start with the correct repr within the unsafe region, and try to find the closest repr // to `v` which is also within the safe region. if we can't, we give up. let plus1 = plus.f + 1; -// let plus0 = plus.f - 1; // only for explanation -// let minus0 = minus.f + 1; // only for explanation + // let plus0 = plus.f - 1; // only for explanation + // let minus0 = minus.f + 1; // only for explanation let minus1 = minus.f - 1; let e = -plus.e as usize; // shared exponent @@ -235,14 +248,15 @@ pub fn format_shortest_opt(d: &Decoded, // (e.g., `x` = 32000, `y` = 32777; `kappa` = 2 since `y mod 10^3 = 777 < y - x = 777`.) // the algorithm relies on the later verification phase to exclude `y`. let delta1 = plus1 - minus1; -// let delta1int = (delta1 >> e) as usize; // only for explanation + // let delta1int = (delta1 >> e) as usize; // only for explanation let delta1frac = delta1 & ((1 << e) - 1); // render integral parts, while checking for the accuracy at each step. let mut kappa = max_kappa as i16; let mut ten_kappa = max_ten_kappa; // 10^kappa let mut remainder = plus1int; // digits yet to be rendered - loop { // we always have at least one digit to render, as `plus1 >= 10^kappa` + loop { + // we always have at least one digit to render, as `plus1 >= 10^kappa` // invariants: // - `delta1int <= remainder < 10^(kappa+1)` // - `plus1int = d[0..n-1] * 10^(kappa+1) + remainder` @@ -281,7 +295,8 @@ pub fn format_shortest_opt(d: &Decoded, let mut remainder = plus1frac; let mut threshold = delta1frac; let mut ulp = 1; - loop { // the next digit should be significant as we've tested that before breaking out + loop { + // the next digit should be significant as we've tested that before breaking out // invariants, where `m = max_kappa + 1` (# of digits in the integral part): // - `remainder < 2^e` // - `plus1frac * 10^(n-m) = d[m..n-1] * 2^e + remainder` @@ -300,8 +315,15 @@ pub fn format_shortest_opt(d: &Decoded, if r < threshold { let ten_kappa = 1 << e; // implicit divisor - return round_and_weed(&mut buf[..i], exp, r, threshold, - (plus1 - v.f) * ulp, ten_kappa, ulp); + return round_and_weed( + &mut buf[..i], + exp, + r, + threshold, + (plus1 - v.f) * ulp, + ten_kappa, + ulp, + ); } // restore invariants @@ -325,8 +347,15 @@ pub fn format_shortest_opt(d: &Decoded, // - `plus1v = (plus1 - v) * k` (and also, `threshold > plus1v` from prior invariants) // - `ten_kappa = 10^kappa * k` // - `ulp = 2^-e * k` - fn round_and_weed(buf: &mut [u8], exp: i16, remainder: u64, threshold: u64, plus1v: u64, - ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> { + fn round_and_weed( + buf: &mut [u8], + exp: i16, + remainder: u64, + threshold: u64, + plus1v: u64, + ten_kappa: u64, + ulp: u64, + ) -> Option<(usize, i16)> { assert!(!buf.is_empty()); // produce two approximations to `v` (actually `plus1 - v`) within 1.5 ulps. @@ -381,10 +410,11 @@ pub fn format_shortest_opt(d: &Decoded, // // consequently, we should stop when `TC1 || TC2 || (TC3a && TC3b)`. the following is // equal to its inverse, `!TC1 && !TC2 && (!TC3a || !TC3b)`. - while plus1w < plus1v_up && - threshold - plus1w >= ten_kappa && - (plus1w + ten_kappa < plus1v_up || - plus1v_up - plus1w >= plus1w + ten_kappa - plus1v_up) { + while plus1w < plus1v_up + && threshold - plus1w >= ten_kappa + && (plus1w + ten_kappa < plus1v_up + || plus1v_up - plus1w >= plus1w + ten_kappa - plus1v_up) + { *last -= 1; debug_assert!(*last > b'0'); // the shortest repr cannot end with `0` plus1w += ten_kappa; @@ -395,10 +425,11 @@ pub fn format_shortest_opt(d: &Decoded, // // this is simply same to the terminating conditions for `v + 1 ulp`, with all `plus1v_up` // replaced by `plus1v_down` instead. overflow analysis equally holds. - if plus1w < plus1v_down && - threshold - plus1w >= ten_kappa && - (plus1w + ten_kappa < plus1v_down || - plus1v_down - plus1w >= plus1w + ten_kappa - plus1v_down) { + if plus1w < plus1v_down + && threshold - plus1w >= ten_kappa + && (plus1w + ten_kappa < plus1v_down + || plus1v_down - plus1w >= plus1w + ten_kappa - plus1v_down) + { return None; } @@ -428,8 +459,11 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp /// The exact and fixed mode implementation for Grisu. /// /// It returns `None` when it would return an inexact representation otherwise. -pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16) - -> Option<(/*#digits*/ usize, /*exp*/ i16)> { +pub fn format_exact_opt( + d: &Decoded, + buf: &mut [u8], + limit: i16, +) -> Option<(/*#digits*/ usize, /*exp*/ i16)> { assert!(d.mant > 0); assert!(d.mant < (1 << 61)); // we need at least three bits of additional precision assert!(!buf.is_empty()); @@ -489,7 +523,8 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16) let mut kappa = max_kappa as i16; let mut ten_kappa = max_ten_kappa; // 10^kappa let mut remainder = vint; // digits yet to be rendered - loop { // we always have at least one digit to render + loop { + // we always have at least one digit to render // invariants: // - `remainder < 10^(kappa+1)` // - `vint = d[0..n-1] * 10^(kappa+1) + remainder` @@ -575,8 +610,15 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16) // - `remainder = (v % 10^kappa) * k` // - `ten_kappa = 10^kappa * k` // - `ulp = 2^-e * k` - fn possibly_round(buf: &mut [u8], mut len: usize, mut exp: i16, limit: i16, - remainder: u64, ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> { + fn possibly_round( + buf: &mut [u8], + mut len: usize, + mut exp: i16, + limit: i16, + remainder: u64, + ten_kappa: u64, + ulp: u64, + ) -> Option<(usize, i16)> { debug_assert!(remainder < ten_kappa); // 10^kappa @@ -593,7 +635,9 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16) // // error is too large that there are at least three possible representations // between `v - 1 ulp` and `v + 1 ulp`. we cannot determine which one is correct. - if ulp >= ten_kappa { return None; } + if ulp >= ten_kappa { + return None; + } // 10^kappa // :<------->: @@ -607,7 +651,9 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16) // in fact, 1/2 ulp is enough to introduce two possible representations. // (remember that we need a unique representation for both `v - 1 ulp` and `v + 1 ulp`.) // this won't overflow, as `ulp < ten_kappa` from the first check. - if ten_kappa - ulp <= ulp { return None; } + if ten_kappa - ulp <= ulp { + return None; + } // remainder // :<->| : diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index 5fe9895d8d2..0ddfbd02aa5 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -4,7 +4,7 @@ use crate::ops::*; #[allow(unused_macros)] macro_rules! sh_impl_signed { - ($t:ident, $f:ident) => ( + ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; @@ -19,7 +19,7 @@ macro_rules! sh_impl_signed { } } forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, - #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } + #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] impl ShlAssign<$f> for Wrapping<$t> { @@ -44,7 +44,7 @@ macro_rules! sh_impl_signed { } } forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, - #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } + #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] impl ShrAssign<$f> for Wrapping<$t> { @@ -54,11 +54,11 @@ macro_rules! sh_impl_signed { } } forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } - ) + }; } macro_rules! sh_impl_unsigned { - ($t:ident, $f:ident) => ( + ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; @@ -69,7 +69,7 @@ macro_rules! sh_impl_unsigned { } } forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, - #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } + #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] impl ShlAssign<$f> for Wrapping<$t> { @@ -90,7 +90,7 @@ macro_rules! sh_impl_unsigned { } } forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, - #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } + #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] impl ShrAssign<$f> for Wrapping<$t> { @@ -100,7 +100,7 @@ macro_rules! sh_impl_unsigned { } } forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } - ) + }; } // FIXME (#23545): uncomment the remaining impls |
