mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-06 08:36:52 -04:00
Rollup merge of #151900 - tgross35:num-internal-imp, r=Mark-Simulacrum
num: Separate public API from internal implementations Currently we have a single `core::num` module that contains both thin wrapper API and higher-complexity numeric routines. Restructure this by moving implementation details to a new `imp` module. This results in a more clean separation of what is actually user-facing compared to items that have a stability attribute because they are public for testing. The first commit does the actual change then the second moves a portion back.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::num::{flt2dec, fmt as numfmt};
|
||||
use crate::num::imp::{flt2dec, fmt as numfmt};
|
||||
|
||||
#[doc(hidden)]
|
||||
trait GeneralFormat: PartialOrd {
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell};
|
||||
use crate::char::EscapeDebugExtArgs;
|
||||
use crate::hint::assert_unchecked;
|
||||
use crate::marker::{PhantomData, PointeeSized};
|
||||
use crate::num::fmt as numfmt;
|
||||
use crate::num::imp::fmt as numfmt;
|
||||
use crate::ops::Deref;
|
||||
use crate::ptr::NonNull;
|
||||
use crate::{iter, mem, result, str};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use crate::fmt::NumBuffer;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::num::fmt as numfmt;
|
||||
use crate::num::imp::fmt as numfmt;
|
||||
use crate::{fmt, str};
|
||||
|
||||
/// Formatting of integers with a non-decimal radix.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
use crate::convert::FloatToInt;
|
||||
use crate::num::FpCategory;
|
||||
#[cfg(not(test))]
|
||||
use crate::num::libm;
|
||||
use crate::num::imp::libm;
|
||||
use crate::panic::const_assert;
|
||||
use crate::{intrinsics, mem};
|
||||
|
||||
|
||||
@@ -1692,7 +1692,7 @@ impl f32 {
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
pub mod math {
|
||||
use crate::intrinsics;
|
||||
use crate::num::libm;
|
||||
use crate::num::imp::libm;
|
||||
|
||||
/// Experimental version of `floor` in `core`. See [`f32::floor`] for details.
|
||||
///
|
||||
|
||||
@@ -1690,7 +1690,7 @@ impl f64 {
|
||||
/// They will be stabilized as inherent methods._
|
||||
pub mod math {
|
||||
use crate::intrinsics;
|
||||
use crate::num::libm;
|
||||
use crate::num::imp::libm;
|
||||
|
||||
/// Experimental version of `floor` in `core`. See [`f64::floor`] for details.
|
||||
///
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
//! User-facing API for float parsing.
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::fmt;
|
||||
use crate::num::imp::dec2flt;
|
||||
use crate::str::FromStr;
|
||||
|
||||
macro_rules! from_str_float_impl {
|
||||
($t:ty) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl FromStr for $t {
|
||||
type Err = ParseFloatError;
|
||||
|
||||
/// Converts a string in base 10 to a float.
|
||||
/// Accepts an optional decimal exponent.
|
||||
///
|
||||
/// This function accepts strings such as
|
||||
///
|
||||
/// * '3.14'
|
||||
/// * '-3.14'
|
||||
/// * '2.5E10', or equivalently, '2.5e10'
|
||||
/// * '2.5E-10'
|
||||
/// * '5.'
|
||||
/// * '.5', or, equivalently, '0.5'
|
||||
/// * '7'
|
||||
/// * '007'
|
||||
/// * 'inf', '-inf', '+infinity', 'NaN'
|
||||
///
|
||||
/// Note that alphabetical characters are not case-sensitive.
|
||||
///
|
||||
/// Leading and trailing whitespace represent an error.
|
||||
///
|
||||
/// # Grammar
|
||||
///
|
||||
/// All strings that adhere to the following [EBNF] grammar when
|
||||
/// lowercased will result in an [`Ok`] being returned:
|
||||
///
|
||||
/// ```txt
|
||||
/// Float ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
|
||||
/// Number ::= ( Digit+ |
|
||||
/// Digit+ '.' Digit* |
|
||||
/// Digit* '.' Digit+ ) Exp?
|
||||
/// Exp ::= 'e' Sign? Digit+
|
||||
/// Sign ::= [+-]
|
||||
/// Digit ::= [0-9]
|
||||
/// ```
|
||||
///
|
||||
/// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * src - A string
|
||||
///
|
||||
/// # Return value
|
||||
///
|
||||
/// `Err(ParseFloatError)` if the string did not represent a valid
|
||||
/// number. Otherwise, `Ok(n)` where `n` is the closest
|
||||
/// representable floating-point number to the number represented
|
||||
/// by `src` (following the same rules for rounding as for the
|
||||
/// results of primitive operations).
|
||||
// We add the `#[inline(never)]` attribute, since its content will
|
||||
// be filled with that of `dec2flt`, which has #[inline(always)].
|
||||
// Since `dec2flt` is generic, a normal inline attribute on this function
|
||||
// with `dec2flt` having no attributes results in heavily repeated
|
||||
// generation of `dec2flt`, despite the fact only a maximum of 2
|
||||
// possible instances can ever exist. Adding #[inline(never)] avoids this.
|
||||
#[inline(never)]
|
||||
fn from_str(src: &str) -> Result<Self, ParseFloatError> {
|
||||
dec2flt::dec2flt(src)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
from_str_float_impl!(f16);
|
||||
from_str_float_impl!(f32);
|
||||
from_str_float_impl!(f64);
|
||||
|
||||
// FIXME(f16): A fallback is used when the backend+target does not support f16 well, in order
|
||||
// to avoid ICEs.
|
||||
|
||||
#[cfg(not(target_has_reliable_f16))]
|
||||
#[expect(ineffective_unstable_trait_impl, reason = "stable trait on unstable type")]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
impl FromStr for f16 {
|
||||
type Err = ParseFloatError;
|
||||
|
||||
#[inline]
|
||||
fn from_str(_src: &str) -> Result<Self, ParseFloatError> {
|
||||
unimplemented!("requires target_has_reliable_f16")
|
||||
}
|
||||
}
|
||||
|
||||
/// An error which can be returned when parsing a float.
|
||||
///
|
||||
/// This error is used as the error type for the [`FromStr`] implementation
|
||||
/// for [`f32`] and [`f64`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::str::FromStr;
|
||||
///
|
||||
/// if let Err(e) = f64::from_str("a.12") {
|
||||
/// println!("Failed conversion to f64: {e}");
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct ParseFloatError {
|
||||
pub(super) kind: FloatErrorKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(super) enum FloatErrorKind {
|
||||
Empty,
|
||||
Invalid,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for ParseFloatError {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for ParseFloatError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.kind {
|
||||
FloatErrorKind::Empty => "cannot parse float from empty string",
|
||||
FloatErrorKind::Invalid => "invalid float literal",
|
||||
}
|
||||
.fmt(f)
|
||||
}
|
||||
}
|
||||
@@ -251,7 +251,7 @@ macro_rules! define_bignum {
|
||||
|
||||
/// Multiplies itself by `5^e` and returns its own mutable reference.
|
||||
pub fn mul_pow5(&mut self, mut e: usize) -> &mut $name {
|
||||
use crate::num::bignum::SMALL_POW5;
|
||||
use crate::num::imp::bignum::SMALL_POW5;
|
||||
|
||||
// There are exactly n trailing zeros on 2^n, and the only relevant digit sizes
|
||||
// are consecutive powers of two, so this is well suited index for the table.
|
||||
@@ -281,7 +281,7 @@ macro_rules! define_bignum {
|
||||
pub fn mul_digits<'a>(&'a mut self, other: &[$ty]) -> &'a mut $name {
|
||||
// the internal routine. works best when aa.len() <= bb.len().
|
||||
fn mul_inner(ret: &mut [$ty; $n], aa: &[$ty], bb: &[$ty]) -> usize {
|
||||
use crate::num::bignum::FullOps;
|
||||
use crate::num::imp::bignum::FullOps;
|
||||
|
||||
let mut retsz = 0;
|
||||
for (i, &a) in aa.iter().enumerate() {
|
||||
@@ -320,7 +320,7 @@ macro_rules! define_bignum {
|
||||
/// Divides itself by a digit-sized `other` and returns its own
|
||||
/// mutable reference *and* the remainder.
|
||||
pub fn div_rem_small(&mut self, other: $ty) -> (&mut $name, $ty) {
|
||||
use crate::num::bignum::FullOps;
|
||||
use crate::num::imp::bignum::FullOps;
|
||||
|
||||
assert!(other > 0);
|
||||
|
||||
+4
-2
@@ -1,7 +1,9 @@
|
||||
//! Representation of a float as the significant digits and exponent.
|
||||
|
||||
use crate::num::dec2flt::float::RawFloat;
|
||||
use crate::num::dec2flt::fpu::set_precision;
|
||||
use dec2flt::float::RawFloat;
|
||||
use dec2flt::fpu::set_precision;
|
||||
|
||||
use crate::num::imp::dec2flt;
|
||||
|
||||
const INT_POW10: [u64; 16] = [
|
||||
1,
|
||||
+3
-1
@@ -9,7 +9,9 @@
|
||||
//! algorithm can be found in "ParseNumberF64 by Simple Decimal Conversion",
|
||||
//! available online: <https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html>.
|
||||
|
||||
use crate::num::dec2flt::common::{ByteSlice, is_8digits};
|
||||
use dec2flt::common::{ByteSlice, is_8digits};
|
||||
|
||||
use crate::num::imp::dec2flt;
|
||||
|
||||
/// A decimal floating-point number, represented as a sequence of decimal digits.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@@ -1,10 +1,10 @@
|
||||
//! Implementation of the Eisel-Lemire algorithm.
|
||||
|
||||
use crate::num::dec2flt::common::BiasedFp;
|
||||
use crate::num::dec2flt::float::RawFloat;
|
||||
use crate::num::dec2flt::table::{
|
||||
LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE,
|
||||
};
|
||||
use dec2flt::common::BiasedFp;
|
||||
use dec2flt::float::RawFloat;
|
||||
use dec2flt::table::{LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE};
|
||||
|
||||
use crate::num::imp::dec2flt;
|
||||
|
||||
/// Compute w * 10^q using an extended-precision float representation.
|
||||
///
|
||||
@@ -87,14 +87,14 @@
|
||||
issue = "none"
|
||||
)]
|
||||
|
||||
use self::common::BiasedFp;
|
||||
use self::float::RawFloat;
|
||||
use self::lemire::compute_float;
|
||||
use self::parse::{parse_inf_nan, parse_number};
|
||||
use self::slow::parse_long_mantissa;
|
||||
use crate::error::Error;
|
||||
use crate::fmt;
|
||||
use crate::str::FromStr;
|
||||
use common::BiasedFp;
|
||||
use float::RawFloat;
|
||||
use lemire::compute_float;
|
||||
use parse::{parse_inf_nan, parse_number};
|
||||
use slow::parse_long_mantissa;
|
||||
|
||||
use crate::num::ParseFloatError;
|
||||
use crate::num::float_parse::FloatErrorKind;
|
||||
|
||||
mod common;
|
||||
pub mod decimal;
|
||||
@@ -107,131 +107,6 @@ pub mod float;
|
||||
pub mod lemire;
|
||||
pub mod parse;
|
||||
|
||||
macro_rules! from_str_float_impl {
|
||||
($t:ty) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl FromStr for $t {
|
||||
type Err = ParseFloatError;
|
||||
|
||||
/// Converts a string in base 10 to a float.
|
||||
/// Accepts an optional decimal exponent.
|
||||
///
|
||||
/// This function accepts strings such as
|
||||
///
|
||||
/// * '3.14'
|
||||
/// * '-3.14'
|
||||
/// * '2.5E10', or equivalently, '2.5e10'
|
||||
/// * '2.5E-10'
|
||||
/// * '5.'
|
||||
/// * '.5', or, equivalently, '0.5'
|
||||
/// * '7'
|
||||
/// * '007'
|
||||
/// * 'inf', '-inf', '+infinity', 'NaN'
|
||||
///
|
||||
/// Note that alphabetical characters are not case-sensitive.
|
||||
///
|
||||
/// Leading and trailing whitespace represent an error.
|
||||
///
|
||||
/// # Grammar
|
||||
///
|
||||
/// All strings that adhere to the following [EBNF] grammar when
|
||||
/// lowercased will result in an [`Ok`] being returned:
|
||||
///
|
||||
/// ```txt
|
||||
/// Float ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
|
||||
/// Number ::= ( Digit+ |
|
||||
/// Digit+ '.' Digit* |
|
||||
/// Digit* '.' Digit+ ) Exp?
|
||||
/// Exp ::= 'e' Sign? Digit+
|
||||
/// Sign ::= [+-]
|
||||
/// Digit ::= [0-9]
|
||||
/// ```
|
||||
///
|
||||
/// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * src - A string
|
||||
///
|
||||
/// # Return value
|
||||
///
|
||||
/// `Err(ParseFloatError)` if the string did not represent a valid
|
||||
/// number. Otherwise, `Ok(n)` where `n` is the closest
|
||||
/// representable floating-point number to the number represented
|
||||
/// by `src` (following the same rules for rounding as for the
|
||||
/// results of primitive operations).
|
||||
// We add the `#[inline(never)]` attribute, since its content will
|
||||
// be filled with that of `dec2flt`, which has #[inline(always)].
|
||||
// Since `dec2flt` is generic, a normal inline attribute on this function
|
||||
// with `dec2flt` having no attributes results in heavily repeated
|
||||
// generation of `dec2flt`, despite the fact only a maximum of 2
|
||||
// possible instances can ever exist. Adding #[inline(never)] avoids this.
|
||||
#[inline(never)]
|
||||
fn from_str(src: &str) -> Result<Self, ParseFloatError> {
|
||||
dec2flt(src)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
from_str_float_impl!(f16);
|
||||
from_str_float_impl!(f32);
|
||||
from_str_float_impl!(f64);
|
||||
|
||||
// FIXME(f16): A fallback is used when the backend+target does not support f16 well, in order
|
||||
// to avoid ICEs.
|
||||
|
||||
#[cfg(not(target_has_reliable_f16))]
|
||||
impl FromStr for f16 {
|
||||
type Err = ParseFloatError;
|
||||
|
||||
#[inline]
|
||||
fn from_str(_src: &str) -> Result<Self, ParseFloatError> {
|
||||
unimplemented!("requires target_has_reliable_f16")
|
||||
}
|
||||
}
|
||||
|
||||
/// An error which can be returned when parsing a float.
|
||||
///
|
||||
/// This error is used as the error type for the [`FromStr`] implementation
|
||||
/// for [`f32`] and [`f64`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::str::FromStr;
|
||||
///
|
||||
/// if let Err(e) = f64::from_str("a.12") {
|
||||
/// println!("Failed conversion to f64: {e}");
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct ParseFloatError {
|
||||
kind: FloatErrorKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum FloatErrorKind {
|
||||
Empty,
|
||||
Invalid,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for ParseFloatError {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for ParseFloatError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.kind {
|
||||
FloatErrorKind::Empty => "cannot parse float from empty string",
|
||||
FloatErrorKind::Invalid => "invalid float literal",
|
||||
}
|
||||
.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn pfe_empty() -> ParseFloatError {
|
||||
ParseFloatError { kind: FloatErrorKind::Empty }
|
||||
@@ -1,8 +1,10 @@
|
||||
//! Functions to parse floating-point numbers.
|
||||
|
||||
use crate::num::dec2flt::common::{ByteSlice, is_8digits};
|
||||
use crate::num::dec2flt::decimal::Decimal;
|
||||
use crate::num::dec2flt::float::RawFloat;
|
||||
use dec2flt::common::{ByteSlice, is_8digits};
|
||||
use dec2flt::decimal::Decimal;
|
||||
use dec2flt::float::RawFloat;
|
||||
|
||||
use crate::num::imp::dec2flt;
|
||||
|
||||
const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
//! Slow, fallback algorithm for cases the Eisel-Lemire algorithm cannot round.
|
||||
|
||||
use crate::num::dec2flt::common::BiasedFp;
|
||||
use crate::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
|
||||
use crate::num::dec2flt::float::RawFloat;
|
||||
use dec2flt::common::BiasedFp;
|
||||
use dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
|
||||
use dec2flt::float::RawFloat;
|
||||
|
||||
use crate::num::imp::dec2flt;
|
||||
|
||||
/// Parse the significant digits and biased, binary exponent of a float.
|
||||
///
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
//! Decodes a floating-point value into individual parts and error ranges.
|
||||
|
||||
use crate::num::FpCategory;
|
||||
use crate::num::dec2flt::float::RawFloat;
|
||||
use crate::num::imp::dec2flt::float::RawFloat;
|
||||
|
||||
/// Decoded unsigned finite value, such that:
|
||||
///
|
||||
+5
-3
@@ -4,11 +4,13 @@
|
||||
//! [^1]: Burger, R. G. and Dybvig, R. K. 1996. Printing floating-point numbers
|
||||
//! quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
|
||||
|
||||
use flt2dec::estimator::estimate_scaling_factor;
|
||||
use flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
|
||||
|
||||
use crate::cmp::Ordering;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::num::bignum::{Big32x40 as Big, Digit32 as Digit};
|
||||
use crate::num::flt2dec::estimator::estimate_scaling_factor;
|
||||
use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
|
||||
use crate::num::imp::bignum::{Big32x40 as Big, Digit32 as Digit};
|
||||
use crate::num::imp::flt2dec;
|
||||
|
||||
static POW10: [Digit; 10] =
|
||||
[1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000];
|
||||
+6
-4
@@ -5,9 +5,11 @@
|
||||
//! [^1]: Florian Loitsch. 2010. Printing floating-point numbers quickly and
|
||||
//! accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
|
||||
|
||||
use flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
|
||||
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::num::diy_float::Fp;
|
||||
use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
|
||||
use crate::num::imp::diy_float::Fp;
|
||||
use crate::num::imp::flt2dec;
|
||||
|
||||
// see the comments in `format_shortest_opt` for the rationale.
|
||||
#[doc(hidden)]
|
||||
@@ -455,7 +457,7 @@ pub fn format_shortest<'a>(
|
||||
d: &Decoded,
|
||||
buf: &'a mut [MaybeUninit<u8>],
|
||||
) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
|
||||
use crate::num::flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
use flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
// SAFETY: The borrow checker is not smart enough to let us use `buf`
|
||||
// in the second branch, so we launder the lifetime here. But we only re-use
|
||||
// `buf` if `format_shortest_opt` returned `None` so this is okay.
|
||||
@@ -765,7 +767,7 @@ pub fn format_exact<'a>(
|
||||
buf: &'a mut [MaybeUninit<u8>],
|
||||
limit: i16,
|
||||
) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
|
||||
use crate::num::flt2dec::strategy::dragon::format_exact as fallback;
|
||||
use flt2dec::strategy::dragon::format_exact as fallback;
|
||||
// SAFETY: The borrow checker is not smart enough to let us use `buf`
|
||||
// in the second branch, so we launder the lifetime here. But we only re-use
|
||||
// `buf` if `format_exact_opt` returned `None` so this is okay.
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
macro_rules! uint_impl {
|
||||
($U:ident) => {
|
||||
pub(super) mod $U {
|
||||
pub(in crate::num) mod $U {
|
||||
const STAGES: usize = $U::BITS.ilog2() as usize;
|
||||
#[inline]
|
||||
const fn prepare(sparse: $U) -> [$U; STAGES] {
|
||||
@@ -100,7 +100,7 @@ macro_rules! uint_impl {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(in super::super) const fn extract_impl(mut x: $U, sparse: $U) -> $U {
|
||||
pub(in crate::num) const fn extract_impl(mut x: $U, sparse: $U) -> $U {
|
||||
let masks = prepare(sparse);
|
||||
x &= sparse;
|
||||
let mut stage = 0;
|
||||
@@ -131,7 +131,7 @@ macro_rules! uint_impl {
|
||||
x
|
||||
}
|
||||
#[inline(always)]
|
||||
pub(in super::super) const fn deposit_impl(mut x: $U, sparse: $U) -> $U {
|
||||
pub(in crate::num) const fn deposit_impl(mut x: $U, sparse: $U) -> $U {
|
||||
let masks = prepare(sparse);
|
||||
let mut stage = STAGES;
|
||||
while stage > 0 {
|
||||
@@ -96,7 +96,7 @@ const fn u128_impl(mut val: u128) -> u32 {
|
||||
macro_rules! define_unsigned_ilog10 {
|
||||
($($ty:ident => $impl_fn:ident,)*) => {$(
|
||||
#[inline]
|
||||
pub(super) const fn $ty(val: NonZero<$ty>) -> u32 {
|
||||
pub(in crate::num) const fn $ty(val: NonZero<$ty>) -> u32 {
|
||||
let result = $impl_fn(val.get());
|
||||
|
||||
// SAFETY: Integer logarithm is monotonic non-decreasing, so the computed `result` cannot
|
||||
@@ -117,7 +117,7 @@ define_unsigned_ilog10! {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) const fn usize(val: NonZero<usize>) -> u32 {
|
||||
pub(in crate::num) const fn usize(val: NonZero<usize>) -> u32 {
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
let impl_fn = u16;
|
||||
|
||||
@@ -136,7 +136,7 @@ macro_rules! define_signed_ilog10 {
|
||||
($($ty:ident => $impl_fn:ident,)*) => {$(
|
||||
// 0 < val <= $ty::MAX
|
||||
#[inline]
|
||||
pub(super) const fn $ty(val: $ty) -> Option<u32> {
|
||||
pub(in crate::num) const fn $ty(val: $ty) -> Option<u32> {
|
||||
if val > 0 {
|
||||
let result = $impl_fn(val.cast_unsigned());
|
||||
|
||||
@@ -166,6 +166,6 @@ define_signed_ilog10! {
|
||||
/// on every single primitive type.
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn panic_for_nonpositive_argument() -> ! {
|
||||
pub(in crate::num) const fn panic_for_nonpositive_argument() -> ! {
|
||||
panic!("argument of integer logarithm must be positive")
|
||||
}
|
||||
@@ -37,7 +37,7 @@ const U8_ISQRT_WITH_REMAINDER: [(u8, u8); 256] = {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub(super) const fn u8(n: u8) -> u8 {
|
||||
pub(in crate::num) const fn u8(n: u8) -> u8 {
|
||||
U8_ISQRT_WITH_REMAINDER[n as usize].0
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ macro_rules! signed_fn {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub(super) const unsafe fn $SignedT(n: $SignedT) -> $SignedT {
|
||||
pub(in crate::num) const unsafe fn $SignedT(n: $SignedT) -> $SignedT {
|
||||
debug_assert!(n >= 0, "Negative input inside `isqrt`.");
|
||||
$UnsignedT(n as $UnsignedT) as $SignedT
|
||||
}
|
||||
@@ -83,7 +83,7 @@ macro_rules! unsigned_fn {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub(super) const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT {
|
||||
pub(in crate::num) const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT {
|
||||
if n <= <$HalfBitsT>::MAX as $UnsignedT {
|
||||
$HalfBitsT(n as $HalfBitsT) as $UnsignedT
|
||||
} else {
|
||||
@@ -311,6 +311,6 @@ unsigned_fn!(u128, u64, u128_stages);
|
||||
/// on every single primitive type.
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn panic_for_negative_argument() -> ! {
|
||||
pub(in crate::num) const fn panic_for_negative_argument() -> ! {
|
||||
panic!("argument of integer square root cannot be negative")
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//! Numeric routines, separate from API.
|
||||
|
||||
// These modules are public only for testing.
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod bignum;
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod dec2flt;
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod diy_float;
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod flt2dec;
|
||||
pub mod fmt;
|
||||
|
||||
pub(crate) mod int_bits;
|
||||
pub(crate) mod int_log10;
|
||||
pub(crate) mod int_sqrt;
|
||||
pub(crate) mod libm;
|
||||
pub(crate) mod overflow_panic;
|
||||
@@ -4,48 +4,48 @@
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn add() -> ! {
|
||||
pub(in crate::num) const fn add() -> ! {
|
||||
panic!("attempt to add with overflow")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn sub() -> ! {
|
||||
pub(in crate::num) const fn sub() -> ! {
|
||||
panic!("attempt to subtract with overflow")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn mul() -> ! {
|
||||
pub(in crate::num) const fn mul() -> ! {
|
||||
panic!("attempt to multiply with overflow")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn div() -> ! {
|
||||
pub(in crate::num) const fn div() -> ! {
|
||||
panic!("attempt to divide with overflow")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn rem() -> ! {
|
||||
pub(in crate::num) const fn rem() -> ! {
|
||||
panic!("attempt to calculate the remainder with overflow")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn neg() -> ! {
|
||||
pub(in crate::num) const fn neg() -> ! {
|
||||
panic!("attempt to negate with overflow")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn shr() -> ! {
|
||||
pub(in crate::num) const fn shr() -> ! {
|
||||
panic!("attempt to shift right with overflow")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub(super) const fn shl() -> ! {
|
||||
pub(in crate::num) const fn shl() -> ! {
|
||||
panic!("attempt to shift left with overflow")
|
||||
}
|
||||
@@ -553,7 +553,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_add(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_add(rhs);
|
||||
if b { overflow_panic::add() } else { a }
|
||||
if b { imp::overflow_panic::add() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked integer addition. Computes `self + rhs`, assuming overflow
|
||||
@@ -643,7 +643,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
|
||||
let (a, b) = self.overflowing_add_unsigned(rhs);
|
||||
if b { overflow_panic::add() } else { a }
|
||||
if b { imp::overflow_panic::add() } else { a }
|
||||
}
|
||||
|
||||
/// Checked integer subtraction. Computes `self - rhs`, returning `None` if
|
||||
@@ -693,7 +693,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_sub(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_sub(rhs);
|
||||
if b { overflow_panic::sub() } else { a }
|
||||
if b { imp::overflow_panic::sub() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
|
||||
@@ -783,7 +783,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
|
||||
let (a, b) = self.overflowing_sub_unsigned(rhs);
|
||||
if b { overflow_panic::sub() } else { a }
|
||||
if b { imp::overflow_panic::sub() } else { a }
|
||||
}
|
||||
|
||||
/// Checked integer multiplication. Computes `self * rhs`, returning `None` if
|
||||
@@ -833,7 +833,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_mul(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_mul(rhs);
|
||||
if b { overflow_panic::mul() } else { a }
|
||||
if b { imp::overflow_panic::mul() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
|
||||
@@ -940,7 +940,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_div(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_div(rhs);
|
||||
if b { overflow_panic::div() } else { a }
|
||||
if b { imp::overflow_panic::div() } else { a }
|
||||
}
|
||||
|
||||
/// Checked Euclidean division. Computes `self.div_euclid(rhs)`,
|
||||
@@ -1007,7 +1007,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_div_euclid(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_div_euclid(rhs);
|
||||
if b { overflow_panic::div() } else { a }
|
||||
if b { imp::overflow_panic::div() } else { a }
|
||||
}
|
||||
|
||||
/// Checked integer division without remainder. Computes `self / rhs`,
|
||||
@@ -1179,7 +1179,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_rem(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_rem(rhs);
|
||||
if b { overflow_panic::rem() } else { a }
|
||||
if b { imp::overflow_panic::rem() } else { a }
|
||||
}
|
||||
|
||||
/// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None`
|
||||
@@ -1245,7 +1245,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_rem_euclid(rhs);
|
||||
if b { overflow_panic::rem() } else { a }
|
||||
if b { imp::overflow_panic::rem() } else { a }
|
||||
}
|
||||
|
||||
/// Checked negation. Computes `-self`, returning `None` if `self == MIN`.
|
||||
@@ -1323,7 +1323,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_neg(self) -> Self {
|
||||
let (a, b) = self.overflowing_neg();
|
||||
if b { overflow_panic::neg() } else { a }
|
||||
if b { imp::overflow_panic::neg() } else { a }
|
||||
}
|
||||
|
||||
/// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger
|
||||
@@ -1379,7 +1379,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_shl(self, rhs: u32) -> Self {
|
||||
let (a, b) = self.overflowing_shl(rhs);
|
||||
if b { overflow_panic::shl() } else { a }
|
||||
if b { imp::overflow_panic::shl() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked shift left. Computes `self << rhs`, assuming that
|
||||
@@ -1558,7 +1558,7 @@ macro_rules! int_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_shr(self, rhs: u32) -> Self {
|
||||
let (a, b) = self.overflowing_shr(rhs);
|
||||
if b { overflow_panic::shr() } else { a }
|
||||
if b { imp::overflow_panic::shr() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked shift right. Computes `self >> rhs`, assuming that
|
||||
@@ -1847,7 +1847,7 @@ macro_rules! int_impl {
|
||||
} else {
|
||||
// SAFETY: Input is nonnegative in this `else` branch.
|
||||
let result = unsafe {
|
||||
crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
|
||||
imp::int_sqrt::$ActualT(self as $ActualT) as $SelfT
|
||||
};
|
||||
|
||||
// Inform the optimizer what the range of outputs is. If
|
||||
@@ -1864,7 +1864,7 @@ macro_rules! int_impl {
|
||||
unsafe {
|
||||
// SAFETY: `<$ActualT>::MAX` is nonnegative.
|
||||
const MAX_RESULT: $SelfT = unsafe {
|
||||
crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
|
||||
imp::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
|
||||
};
|
||||
|
||||
crate::hint::assert_unchecked(result >= 0);
|
||||
@@ -3142,7 +3142,7 @@ macro_rules! int_impl {
|
||||
pub const fn isqrt(self) -> Self {
|
||||
match self.checked_isqrt() {
|
||||
Some(sqrt) => sqrt,
|
||||
None => crate::num::int_sqrt::panic_for_negative_argument(),
|
||||
None => imp::int_sqrt::panic_for_negative_argument(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3448,7 +3448,7 @@ macro_rules! int_impl {
|
||||
if let Some(log) = self.checked_ilog(base) {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
imp::int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3473,7 +3473,7 @@ macro_rules! int_impl {
|
||||
if let Some(log) = self.checked_ilog2() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
imp::int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3498,7 +3498,7 @@ macro_rules! int_impl {
|
||||
if let Some(log) = self.checked_ilog10() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
imp::int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3570,7 +3570,7 @@ macro_rules! int_impl {
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_ilog10(self) -> Option<u32> {
|
||||
int_log10::$ActualT(self as $ActualT)
|
||||
imp::int_log10::$ActualT(self as $ActualT)
|
||||
}
|
||||
|
||||
/// Computes the absolute value of `self`.
|
||||
|
||||
+13
-18
@@ -27,16 +27,14 @@ macro_rules! sign_dependent_expr {
|
||||
};
|
||||
}
|
||||
|
||||
// All these modules are technically private and only exposed for coretests:
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod bignum;
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod dec2flt;
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod diy_float;
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod flt2dec;
|
||||
pub mod fmt;
|
||||
// These modules are public only for testing.
|
||||
#[doc(hidden)]
|
||||
#[unstable(
|
||||
feature = "num_internals",
|
||||
reason = "internal routines only exposed for testing",
|
||||
issue = "none"
|
||||
)]
|
||||
pub mod imp;
|
||||
|
||||
#[macro_use]
|
||||
mod int_macros; // import int_impl!
|
||||
@@ -44,12 +42,9 @@ mod int_macros; // import int_impl!
|
||||
mod uint_macros; // import uint_impl!
|
||||
|
||||
mod error;
|
||||
mod int_bits;
|
||||
mod int_log10;
|
||||
mod int_sqrt;
|
||||
pub(crate) mod libm;
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
mod float_parse;
|
||||
mod nonzero;
|
||||
mod overflow_panic;
|
||||
mod saturating;
|
||||
mod wrapping;
|
||||
|
||||
@@ -57,15 +52,15 @@ mod wrapping;
|
||||
#[doc(hidden)]
|
||||
pub mod niche_types;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub use dec2flt::ParseFloatError;
|
||||
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
||||
pub use error::IntErrorKind;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use error::ParseIntError;
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
pub use error::TryFromIntError;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub use float_parse::ParseFloatError;
|
||||
#[stable(feature = "generic_nonzero", since = "1.79.0")]
|
||||
pub use nonzero::NonZero;
|
||||
#[unstable(
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::clone::{TrivialClone, UseCloned};
|
||||
use crate::cmp::Ordering;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::marker::{Destruct, Freeze, StructuralPartialEq};
|
||||
use crate::num::imp;
|
||||
use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
|
||||
use crate::panic::{RefUnwindSafe, UnwindSafe};
|
||||
use crate::str::FromStr;
|
||||
@@ -1817,7 +1818,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn ilog10(self) -> u32 {
|
||||
super::int_log10::$Int(self)
|
||||
imp::int_log10::$Int(self)
|
||||
}
|
||||
|
||||
/// Calculates the midpoint (average) between `self` and `rhs`.
|
||||
|
||||
@@ -574,7 +574,7 @@ macro_rules! uint_impl {
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn extract_bits(self, mask: Self) -> Self {
|
||||
crate::num::int_bits::$ActualT::extract_impl(self as $ActualT, mask as $ActualT) as $SelfT
|
||||
imp::int_bits::$ActualT::extract_impl(self as $ActualT, mask as $ActualT) as $SelfT
|
||||
}
|
||||
|
||||
/// Returns an integer with the least significant bits of `self`
|
||||
@@ -591,7 +591,7 @@ macro_rules! uint_impl {
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn deposit_bits(self, mask: Self) -> Self {
|
||||
crate::num::int_bits::$ActualT::deposit_impl(self as $ActualT, mask as $ActualT) as $SelfT
|
||||
imp::int_bits::$ActualT::deposit_impl(self as $ActualT, mask as $ActualT) as $SelfT
|
||||
}
|
||||
|
||||
/// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit,
|
||||
@@ -802,7 +802,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_add(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_add(rhs);
|
||||
if b { overflow_panic::add() } else { a }
|
||||
if b { imp::overflow_panic::add() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked integer addition. Computes `self + rhs`, assuming overflow
|
||||
@@ -897,7 +897,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
|
||||
let (a, b) = self.overflowing_add_signed(rhs);
|
||||
if b { overflow_panic::add() } else { a }
|
||||
if b { imp::overflow_panic::add() } else { a }
|
||||
}
|
||||
|
||||
/// Checked integer subtraction. Computes `self - rhs`, returning
|
||||
@@ -956,7 +956,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_sub(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_sub(rhs);
|
||||
if b { overflow_panic::sub() } else { a }
|
||||
if b { imp::overflow_panic::sub() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
|
||||
@@ -1081,7 +1081,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_sub_signed(self, rhs: $SignedT) -> Self {
|
||||
let (a, b) = self.overflowing_sub_signed(rhs);
|
||||
if b { overflow_panic::sub() } else { a }
|
||||
if b { imp::overflow_panic::sub() } else { a }
|
||||
}
|
||||
|
||||
#[doc = concat!(
|
||||
@@ -1190,7 +1190,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_mul(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_mul(rhs);
|
||||
if b { overflow_panic::mul() } else { a }
|
||||
if b { imp::overflow_panic::mul() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
|
||||
@@ -1615,7 +1615,7 @@ macro_rules! uint_impl {
|
||||
if let Some(log) = self.checked_ilog(base) {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
imp::int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1640,7 +1640,7 @@ macro_rules! uint_impl {
|
||||
if let Some(log) = self.checked_ilog2() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
imp::int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1665,7 +1665,7 @@ macro_rules! uint_impl {
|
||||
if let Some(log) = self.checked_ilog10() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
imp::int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1827,7 +1827,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_neg(self) -> Self {
|
||||
let (a, b) = self.overflowing_neg();
|
||||
if b { overflow_panic::neg() } else { a }
|
||||
if b { imp::overflow_panic::neg() } else { a }
|
||||
}
|
||||
|
||||
/// Checked shift left. Computes `self << rhs`, returning `None`
|
||||
@@ -1883,7 +1883,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_shl(self, rhs: u32) -> Self {
|
||||
let (a, b) = self.overflowing_shl(rhs);
|
||||
if b { overflow_panic::shl() } else { a }
|
||||
if b { imp::overflow_panic::shl() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked shift left. Computes `self << rhs`, assuming that
|
||||
@@ -2068,7 +2068,7 @@ macro_rules! uint_impl {
|
||||
#[track_caller]
|
||||
pub const fn strict_shr(self, rhs: u32) -> Self {
|
||||
let (a, b) = self.overflowing_shr(rhs);
|
||||
if b { overflow_panic::shr() } else { a }
|
||||
if b { imp::overflow_panic::shr() } else { a }
|
||||
}
|
||||
|
||||
/// Unchecked shift right. Computes `self >> rhs`, assuming that
|
||||
@@ -3541,7 +3541,7 @@ macro_rules! uint_impl {
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn isqrt(self) -> Self {
|
||||
let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
|
||||
let result = imp::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
|
||||
|
||||
// Inform the optimizer what the range of outputs is. If testing
|
||||
// `core` crashes with no panic message and a `num::int_sqrt::u*`
|
||||
@@ -3554,7 +3554,7 @@ macro_rules! uint_impl {
|
||||
// integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
|
||||
// bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
|
||||
unsafe {
|
||||
const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
|
||||
const MAX_RESULT: $SelfT = imp::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
|
||||
crate::hint::assert_unchecked(result <= MAX_RESULT);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ mod strategy {
|
||||
mod grisu;
|
||||
}
|
||||
|
||||
use core::num::flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
|
||||
use core::num::imp::flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
|
||||
use std::io::Write;
|
||||
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::num::flt2dec::strategy::dragon::*;
|
||||
use core::num::imp::flt2dec::strategy::dragon::*;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use super::super::*;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::num::flt2dec::strategy::grisu::*;
|
||||
use core::num::imp::flt2dec::strategy::grisu::*;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use super::super::*;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use core::num::bignum::Big32x40;
|
||||
use core::num::bignum::tests::Big8x3 as Big;
|
||||
use core::num::imp::bignum::Big32x40;
|
||||
use core::num::imp::bignum::tests::Big8x3 as Big;
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::num::dec2flt::decimal::Decimal;
|
||||
use core::num::imp::dec2flt::decimal::Decimal;
|
||||
|
||||
type FPath<F> = ((i64, u64, bool, bool), Option<F>);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
|
||||
use core::num::imp::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
|
||||
|
||||
#[test]
|
||||
fn test_trim() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::num::dec2flt::float::RawFloat;
|
||||
use core::num::imp::dec2flt::float::RawFloat;
|
||||
|
||||
use crate::num::{ldexp_f32, ldexp_f64};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use core::num::dec2flt::float::RawFloat;
|
||||
use core::num::dec2flt::lemire::compute_float;
|
||||
use core::num::imp::dec2flt;
|
||||
|
||||
use dec2flt::float::RawFloat;
|
||||
use dec2flt::lemire::compute_float;
|
||||
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn compute_float16(q: i64, w: u64) -> (i32, u64) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use core::num::dec2flt::decimal::Decimal;
|
||||
use core::num::dec2flt::parse::parse_number;
|
||||
use core::num::dec2flt::{dec2flt, pfe_invalid};
|
||||
use core::num::imp::dec2flt;
|
||||
|
||||
use dec2flt::decimal::Decimal;
|
||||
use dec2flt::parse::parse_number;
|
||||
use dec2flt::{dec2flt, pfe_invalid};
|
||||
|
||||
fn new_dec(e: i64, m: u64) -> Decimal {
|
||||
Decimal { exponent: e, mantissa: m, negative: false, many_digits: false }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::num::flt2dec::estimator::*;
|
||||
use core::num::imp::flt2dec::estimator::*;
|
||||
|
||||
use crate::num::ldexp_f64;
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
use core::num::flt2dec::{
|
||||
use core::num::imp::flt2dec::{
|
||||
DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, Sign, decode, round_up, to_exact_exp_str,
|
||||
to_exact_fixed_str, to_shortest_exp_str, to_shortest_str,
|
||||
};
|
||||
use core::num::fmt::{Formatted, Part};
|
||||
use core::num::imp::fmt::{Formatted, Part};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::{fmt, str};
|
||||
|
||||
use Sign::{Minus, MinusPlus};
|
||||
|
||||
use crate::num::{ldexp_f32, ldexp_f64};
|
||||
|
||||
mod estimator;
|
||||
@@ -562,8 +564,6 @@ pub fn to_shortest_str_test<F>(mut f_: F)
|
||||
where
|
||||
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
|
||||
{
|
||||
use core::num::flt2dec::Sign::*;
|
||||
|
||||
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
|
||||
where
|
||||
T: DecodableFloat,
|
||||
@@ -672,8 +672,6 @@ pub fn to_shortest_exp_str_test<F>(mut f_: F)
|
||||
where
|
||||
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
|
||||
{
|
||||
use core::num::flt2dec::Sign::*;
|
||||
|
||||
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String
|
||||
where
|
||||
T: DecodableFloat,
|
||||
@@ -789,8 +787,6 @@ pub fn to_exact_exp_str_test<F>(mut f_: F)
|
||||
where
|
||||
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
|
||||
{
|
||||
use core::num::flt2dec::Sign::*;
|
||||
|
||||
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String
|
||||
where
|
||||
T: DecodableFloat,
|
||||
@@ -1065,8 +1061,6 @@ pub fn to_exact_fixed_str_test<F>(mut f_: F)
|
||||
where
|
||||
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
|
||||
{
|
||||
use core::num::flt2dec::Sign::*;
|
||||
|
||||
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
|
||||
where
|
||||
T: DecodableFloat,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#![cfg(not(target_arch = "wasm32"))]
|
||||
|
||||
use core::num::flt2dec::strategy::grisu::{format_exact_opt, format_shortest_opt};
|
||||
use core::num::flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
|
||||
use core::num::imp::flt2dec;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::str;
|
||||
|
||||
use flt2dec::strategy::grisu::{format_exact_opt, format_shortest_opt};
|
||||
use flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
|
||||
use rand::distr::{Distribution, Uniform};
|
||||
|
||||
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
|
||||
@@ -159,7 +160,7 @@ where
|
||||
|
||||
#[test]
|
||||
fn shortest_random_equivalence_test() {
|
||||
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
use flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
// Miri is too slow
|
||||
let n = if cfg!(miri) { 10 } else { 10_000 };
|
||||
|
||||
@@ -174,7 +175,7 @@ fn shortest_random_equivalence_test() {
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn shortest_f16_exhaustive_equivalence_test() {
|
||||
// see the f32 version
|
||||
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
use flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
f16_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
|
||||
}
|
||||
|
||||
@@ -188,7 +189,7 @@ fn shortest_f32_exhaustive_equivalence_test() {
|
||||
// with `--nocapture` (and plenty of time and appropriate rustc flags), this should print:
|
||||
// `done, ignored=17643158 passed=2121451881 failed=0`.
|
||||
|
||||
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
use flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
|
||||
}
|
||||
|
||||
@@ -197,14 +198,14 @@ fn shortest_f32_exhaustive_equivalence_test() {
|
||||
fn shortest_f64_hard_random_equivalence_test() {
|
||||
// this again probably has to use appropriate rustc flags.
|
||||
|
||||
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
use flt2dec::strategy::dragon::format_shortest as fallback;
|
||||
f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 100_000_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn exact_f16_random_equivalence_test() {
|
||||
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
|
||||
use flt2dec::strategy::dragon::format_exact as fallback;
|
||||
// Miri is too slow
|
||||
let n = if cfg!(miri) { 3 } else { 1_000 };
|
||||
|
||||
@@ -220,7 +221,7 @@ fn exact_f16_random_equivalence_test() {
|
||||
|
||||
#[test]
|
||||
fn exact_f32_random_equivalence_test() {
|
||||
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
|
||||
use flt2dec::strategy::dragon::format_exact as fallback;
|
||||
// Miri is too slow
|
||||
let n = if cfg!(miri) { 3 } else { 1_000 };
|
||||
|
||||
@@ -236,7 +237,7 @@ fn exact_f32_random_equivalence_test() {
|
||||
|
||||
#[test]
|
||||
fn exact_f64_random_equivalence_test() {
|
||||
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
|
||||
use flt2dec::strategy::dragon::format_exact as fallback;
|
||||
// Miri is too slow
|
||||
let n = if cfg!(miri) { 2 } else { 1_000 };
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use core::num::bignum::Big32x40 as Big;
|
||||
use core::num::flt2dec::strategy::dragon::*;
|
||||
use core::num::imp::bignum::Big32x40 as Big;
|
||||
use core::num::imp::flt2dec::strategy::dragon::*;
|
||||
|
||||
use super::super::*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::num::flt2dec::strategy::grisu::*;
|
||||
use core::num::imp::flt2dec::strategy::grisu::*;
|
||||
|
||||
use super::super::*;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ pub unsafe fn add(a: u8, b: u8) -> u8 {
|
||||
// CHECK: i8 noundef{{( zeroext)?}} %a, i8 noundef{{( zeroext)?}} %b
|
||||
// CHECK: add i8 %b, %a
|
||||
// DEBUG: icmp ult i8 [[zero:[^,]+]], %a
|
||||
// DEBUG: call core::num::overflow_panic::add
|
||||
// DEBUG: call core::num::imp::overflow_panic::add
|
||||
// DEBUG: unreachable
|
||||
// NOCHECKS-NOT: unreachable
|
||||
// NOCHECKS: ret i8 %0
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
let mut _7: isize;
|
||||
let mut _9: &mut std::fmt::Formatter<'_>;
|
||||
let mut _10: &T;
|
||||
let mut _11: core::num::flt2dec::Sign;
|
||||
let mut _11: core::num::imp::flt2dec::Sign;
|
||||
let mut _12: u32;
|
||||
let mut _13: u32;
|
||||
let mut _14: usize;
|
||||
let mut _15: bool;
|
||||
let mut _16: &mut std::fmt::Formatter<'_>;
|
||||
let mut _17: &T;
|
||||
let mut _18: core::num::flt2dec::Sign;
|
||||
let mut _18: core::num::imp::flt2dec::Sign;
|
||||
let mut _19: bool;
|
||||
scope 1 {
|
||||
debug force_sign => _4;
|
||||
let _5: core::num::flt2dec::Sign;
|
||||
let _5: core::num::imp::flt2dec::Sign;
|
||||
scope 2 {
|
||||
debug sign => _5;
|
||||
scope 3 {
|
||||
@@ -56,14 +56,14 @@
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _5 = core::num::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _5 = core::num::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::flt2dec::Sign::Minus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
let mut _7: isize;
|
||||
let mut _9: &mut std::fmt::Formatter<'_>;
|
||||
let mut _10: &T;
|
||||
let mut _11: core::num::flt2dec::Sign;
|
||||
let mut _11: core::num::imp::flt2dec::Sign;
|
||||
let mut _12: u32;
|
||||
let mut _13: u32;
|
||||
let mut _14: usize;
|
||||
let mut _15: bool;
|
||||
let mut _16: &mut std::fmt::Formatter<'_>;
|
||||
let mut _17: &T;
|
||||
let mut _18: core::num::flt2dec::Sign;
|
||||
let mut _18: core::num::imp::flt2dec::Sign;
|
||||
let mut _19: bool;
|
||||
scope 1 {
|
||||
debug force_sign => _4;
|
||||
let _5: core::num::flt2dec::Sign;
|
||||
let _5: core::num::imp::flt2dec::Sign;
|
||||
scope 2 {
|
||||
debug sign => _5;
|
||||
scope 3 {
|
||||
@@ -56,14 +56,14 @@
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _5 = core::num::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _5 = core::num::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::flt2dec::Sign::Minus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
let mut _7: isize;
|
||||
let mut _9: &mut std::fmt::Formatter<'_>;
|
||||
let mut _10: &T;
|
||||
let mut _11: core::num::flt2dec::Sign;
|
||||
let mut _11: core::num::imp::flt2dec::Sign;
|
||||
let mut _12: u32;
|
||||
let mut _13: u32;
|
||||
let mut _14: usize;
|
||||
let mut _15: bool;
|
||||
let mut _16: &mut std::fmt::Formatter<'_>;
|
||||
let mut _17: &T;
|
||||
let mut _18: core::num::flt2dec::Sign;
|
||||
let mut _18: core::num::imp::flt2dec::Sign;
|
||||
let mut _19: bool;
|
||||
scope 1 {
|
||||
debug force_sign => _4;
|
||||
let _5: core::num::flt2dec::Sign;
|
||||
let _5: core::num::imp::flt2dec::Sign;
|
||||
scope 2 {
|
||||
debug sign => _5;
|
||||
scope 3 {
|
||||
@@ -56,14 +56,14 @@
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _5 = core::num::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _5 = core::num::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::flt2dec::Sign::Minus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
let mut _7: isize;
|
||||
let mut _9: &mut std::fmt::Formatter<'_>;
|
||||
let mut _10: &T;
|
||||
let mut _11: core::num::flt2dec::Sign;
|
||||
let mut _11: core::num::imp::flt2dec::Sign;
|
||||
let mut _12: u32;
|
||||
let mut _13: u32;
|
||||
let mut _14: usize;
|
||||
let mut _15: bool;
|
||||
let mut _16: &mut std::fmt::Formatter<'_>;
|
||||
let mut _17: &T;
|
||||
let mut _18: core::num::flt2dec::Sign;
|
||||
let mut _18: core::num::imp::flt2dec::Sign;
|
||||
let mut _19: bool;
|
||||
scope 1 {
|
||||
debug force_sign => _4;
|
||||
let _5: core::num::flt2dec::Sign;
|
||||
let _5: core::num::imp::flt2dec::Sign;
|
||||
scope 2 {
|
||||
debug sign => _5;
|
||||
scope 3 {
|
||||
@@ -56,14 +56,14 @@
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _5 = core::num::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _5 = core::num::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::flt2dec::Sign::Minus;
|
||||
- _5 = core::num::imp::flt2dec::Sign::Minus;
|
||||
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
#![feature(flt2dec)]
|
||||
#![feature(num_internals)]
|
||||
|
||||
extern crate core;
|
||||
|
||||
use core::num::flt2dec;
|
||||
use core::num::imp::flt2dec;
|
||||
use std::fmt::{Formatter, Result};
|
||||
|
||||
// EMIT_MIR funky_arms.float_to_exponential_common.GVN.diff
|
||||
|
||||
+1
-1
@@ -1075,7 +1075,7 @@ gets adapted for the changes, if necessary.
|
||||
"""
|
||||
cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"]
|
||||
|
||||
[mentions."library/core/src/num/{dec2flt,flt2dec}"]
|
||||
[mentions."library/core/src/num/imp/{dec2flt,flt2dec}"]
|
||||
message = "Some changes occurred in float parsing"
|
||||
cc = ["@tgross35"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user