Struct DecimalSeq

pub struct DecimalSeq { pub num_digits: usize, pub decimal_point: i32, pub truncated: bool, pub digits: [u8; 768] }

A decimal floating-point number, represented as a sequence of decimal digits.

Fields

num_digits: usize

The number of significant digits in the decimal.

decimal_point: i32

The offset of the decimal point in the significant digits.

truncated: bool

If the number of significant digits stored in the decimal is truncated.

digits: [u8; 768]

Buffer of the raw digits, in the range [0, 9].

Implementations

impl DecimalSeq

const MAX_DIGITS: usize = 768;

The maximum number of digits required to unambiguously round up to a 64-bit float.

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:

−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋

For f32, this follows as: emin = -126 p2 = 24

For f64, this follows as: emin = -1022 p2 = 53

In Python: -emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))

const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19;

The max decimal digits that can be exactly represented in a 64-bit integer.

const DECIMAL_POINT_RANGE: i32 = 2047;
fn try_add_digit(&mut self, digit: u8)

Append a digit to the buffer if it fits.

fn trim(&mut self)

Trim trailing zeros from the buffer.

fn round(&self) -> u64
fn left_shift(&mut self, shift: usize)

Computes decimal * 2^shift.

fn right_shift(&mut self, shift: usize)

Computes decimal * 2^-shift.

Trait Implementations

impl Clone for DecimalSeq

fn clone(&self) -> DecimalSeq

impl Debug for DecimalSeq

fn fmt(&self, f: &mut Formatter<'_>) -> Result

impl Default for DecimalSeq

fn default() -> Self

impl PartialEq for DecimalSeq

fn eq(&self, other: &DecimalSeq) -> bool

impl StructuralPartialEq for DecimalSeq

Auto Trait Implementations

impl Freeze for DecimalSeq

impl RefUnwindSafe for DecimalSeq

impl Send for DecimalSeq

impl Sync for DecimalSeq

impl Unpin for DecimalSeq

impl UnsafeUnpin for DecimalSeq

impl UnwindSafe for DecimalSeq

Blanket Implementations

impl<T> Any for DecimalSeq where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for DecimalSeq where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for DecimalSeq where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> CloneToUninit for DecimalSeq where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

impl<T> From<T> for DecimalSeq

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> SizeHint for DecimalSeq where T: ?Sized,

fn lower_bound(&self) -> usize
fn upper_bound(&self) -> Option<usize>

impl<T> SizedTypeProperties for DecimalSeq

impl<T, U> Into<U> for DecimalSeq where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for DecimalSeq where U: Into<T>,

type Error = Infallible;
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

impl<T, U> TryInto<U> for DecimalSeq where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>