Skip to content
New issue

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

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

Already on GitHub? # to your account

Optimize parse_str_radix_10 #456

Closed
wants to merge 9 commits into from
5 changes: 5 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,8 @@ pub const MAX_I32_SCALE: i32 = 9;
pub const MAX_I64_SCALE: u32 = 19;
#[cfg(not(feature = "legacy-ops"))]
pub const U32_MAX: u64 = u32::MAX as u64;

// Determines potential overflow for 128 bit operations
pub const OVERFLOW_U96: u128 = 1u128 << 96;
pub const WILL_OVERFLOW_U64: u64 = u64::MAX / 10 - u8::MAX as u64;
pub const BYTES_TO_OVERFLOW_U64: usize = 18; // We can probably get away with less
2 changes: 1 addition & 1 deletion src/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const NEGATIVE_ONE: Decimal = Decimal {

/// `UnpackedDecimal` contains unpacked representation of `Decimal` where each component
/// of decimal-format stored in it's own field
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct UnpackedDecimal {
pub negative: bool,
pub scale: u32,
Expand Down
7 changes: 6 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::constants::MAX_PRECISION_U32;
use crate::{constants::MAX_PRECISION_U32, Decimal};
use alloc::string::String;
use core::fmt;

Expand All @@ -21,6 +21,11 @@ where
}
}

#[cold]
pub(crate) fn tail_error(from: &'static str) -> Result<Decimal, Error> {
Err(from.into())
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}

Expand Down
20 changes: 20 additions & 0 deletions src/ops/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub(crate) fn rescale_internal(value: &mut [u32; 3], value_scale: &mut u32, new_
}
}

#[cfg(feature = "legacy-ops")]
pub(crate) fn add_by_internal(value: &mut [u32], by: &[u32]) -> u32 {
let mut carry: u64 = 0;
let vl = value.len();
Expand Down Expand Up @@ -92,6 +93,25 @@ pub(crate) fn add_by_internal(value: &mut [u32], by: &[u32]) -> u32 {
carry as u32
}

pub(crate) fn add_by_internal_flattened(value: &mut [u32; 3], by: u32) -> u32 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I previously had something similar - add_by_internal3. At some stage I'd love to move away from these functions however it makes sense to introduce it for this PR.

let mut carry: u64;
let mut sum: u64;
sum = u64::from(value[0]) + u64::from(by);
value[0] = (sum & U32_MASK) as u32;
carry = sum >> 32;
if carry > 0 {
sum = u64::from(value[1]) + carry;
value[1] = (sum & U32_MASK) as u32;
carry = sum >> 32;
if carry > 0 {
sum = u64::from(value[2]) + carry;
value[2] = (sum & U32_MASK) as u32;
carry = sum >> 32;
}
}
carry as u32
}

#[inline]
pub(crate) fn add_one_internal(value: &mut [u32]) -> u32 {
let mut carry: u64 = 1; // Start with one, since adding one
Expand Down
Loading