Skip to content

dec2flt: Clean up float parsing modules #134063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions library/core/src/num/dec2flt/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ pub(crate) trait ByteSlice {
/// Writes a 64-bit integer as 8 bytes in little-endian order.
fn write_u64(&mut self, value: u64);

/// Calculate the offset of a slice from another.
/// Calculate the difference in length between two slices.
fn offset_from(&self, other: &Self) -> isize;

/// Iteratively parse and consume digits from bytes.
/// Returns the same bytes with consumed digits being
/// elided.
///
/// Returns the same bytes with consumed digits being elided. Breaks on invalid digits.
fn parse_digits(&self, func: impl FnMut(u8)) -> &Self;
}

Expand All @@ -39,11 +39,11 @@ impl ByteSlice for [u8] {
fn parse_digits(&self, mut func: impl FnMut(u8)) -> &Self {
let mut s = self;

while let Some((c, s_next)) = s.split_first() {
while let Some((c, rest)) = s.split_first() {
let c = c.wrapping_sub(b'0');
if c < 10 {
func(c);
s = s_next;
s = rest;
} else {
break;
}
Expand All @@ -53,27 +53,30 @@ impl ByteSlice for [u8] {
}
}

/// Determine if 8 bytes are all decimal digits.
/// Determine if all characters in an 8-byte byte string (represented as a `u64`) are all decimal
/// digits.
///
/// This does not care about the order in which the bytes were loaded.
pub(crate) fn is_8digits(v: u64) -> bool {
let a = v.wrapping_add(0x4646_4646_4646_4646);
let b = v.wrapping_sub(0x3030_3030_3030_3030);
(a | b) & 0x8080_8080_8080_8080 == 0
}

/// A custom 64-bit floating point type, representing `f * 2^e`.
/// e is biased, so it be directly shifted into the exponent bits.
/// A custom 64-bit floating point type, representing `m * 2^p`.
/// p is biased, so it be directly shifted into the exponent bits.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub struct BiasedFp {
/// The significant digits.
pub f: u64,
pub m: u64,
/// The biased, binary exponent.
pub e: i32,
pub p_biased: i32,
}

impl BiasedFp {
/// Represent `0 ^ p`
#[inline]
pub const fn zero_pow2(e: i32) -> Self {
Self { f: 0, e }
pub const fn zero_pow2(p_biased: i32) -> Self {
Self { m: 0, p_biased }
}
}
Loading
Loading