Skip to content

Commit

Permalink
Misc updates
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Jul 24, 2024
1 parent 781a09b commit 5e324cf
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 16 deletions.
13 changes: 7 additions & 6 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 {
/// Write 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,7 +53,7 @@ impl ByteSlice for [u8] {
}
}

/// Determine if 8 bytes are all decimal digits.
/// Determine if 8 bytes in a 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);
Expand All @@ -72,6 +72,7 @@ pub struct BiasedFp {
}

impl BiasedFp {
/// Represent `0 ^ n`
#[inline]
pub const fn zero_pow2(e: i32) -> Self {
Self { f: 0, e }
Expand Down
20 changes: 11 additions & 9 deletions library/core/src/num/dec2flt/decimal.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Arbitrary-precision decimal class for fallback algorithms.
//! Arbitrary-precision decimal type used by fallback algorithms.
//!
//! This is only used if the fast-path (native floats) and
//! the Eisel-Lemire algorithm are unable to unambiguously
Expand All @@ -11,6 +11,7 @@

use crate::num::dec2flt::common::{is_8digits, ByteSlice};

/// A decimal floating-point number.
#[derive(Clone)]
pub struct Decimal {
/// The number of significant digits in the decimal.
Expand All @@ -30,18 +31,17 @@ impl Default for Decimal {
}

impl Decimal {
/// The maximum number of digits required to unambiguously round a float.
/// The maximum number of digits required to unambiguously round up to a 64-bit float.
///
/// For a double-precision IEEE 754 float, this required 767 digits,
/// so we store the max digits + 1.
/// For an IEEE 754 binary64 float, this required 767 digits. So we store the max digits + 1.
///
/// We can exactly represent a float in radix `b` from radix 2 if
/// `b` is divisible by 2. This function calculates the exact number of
/// digits required to exactly represent that float.
///
/// According to the "Handbook of Floating Point Arithmetic",
/// for IEEE754, with emin being the min exponent, p2 being the
/// precision, and b being the radix, the number of digits follows as:
/// for IEEE754, with `emin` being the min exponent, `p2` being the
/// precision, and `b` being the radix, the number of digits follows as:
///
/// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
///
Expand All @@ -56,11 +56,12 @@ impl Decimal {
/// In Python:
/// `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))`
pub const MAX_DIGITS: usize = 768;
/// The max digits that can be exactly represented in a 64-bit integer.
/// The max decimal digits that can be exactly represented in a 64-bit integer.
pub const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19;
pub const DECIMAL_POINT_RANGE: i32 = 2047;

/// Append a digit to the buffer.
/// Append a digit to the buffer if it fits.
// TODO: looks like this

Check failure on line 64 in library/core/src/num/dec2flt/decimal.rs

View workflow job for this annotation

GitHub Actions / PR - mingw-check-tidy

TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME
pub fn try_add_digit(&mut self, digit: u8) {
if self.num_digits < Self::MAX_DIGITS {
self.digits[self.num_digits] = digit;
Expand All @@ -69,6 +70,7 @@ impl Decimal {
}

/// Trim trailing zeros from the buffer.
// TODO: switch to `.rev().position()`

Check failure on line 73 in library/core/src/num/dec2flt/decimal.rs

View workflow job for this annotation

GitHub Actions / PR - mingw-check-tidy

TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME
pub fn trim(&mut self) {
// All of the following calls to `Decimal::trim` can't panic because:
//
Expand All @@ -86,7 +88,7 @@ impl Decimal {
pub fn round(&self) -> u64 {
if self.num_digits == 0 || self.decimal_point < 0 {
return 0;
} else if self.decimal_point > 18 {
} else if self.decimal_point >= Self::MAX_DIGITS_WITHOUT_OVERFLOW as i32 {
return 0xFFFF_FFFF_FFFF_FFFF_u64;
}
let dp = self.decimal_point as usize;
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/num/dec2flt/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl RawFloat for f16 {
}

fn classify(self) -> FpCategory {
todo!()
self.classify()
}
}

Expand Down

0 comments on commit 5e324cf

Please sign in to comment.