Skip to content

Commit

Permalink
Merge pull request #4 from carlosga/3-bid128_add
Browse files Browse the repository at this point in the history
Closes #4
  • Loading branch information
carlosga authored Jan 23, 2024
2 parents 0ef83e5 + 7de996f commit b41601b
Show file tree
Hide file tree
Showing 16 changed files with 3,542 additions and 25 deletions.
5 changes: 3 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[build]
rustflags=["--cfg", "default_rounding=\"UP\""]
rustdocflags=["--cfg", "default_rounding=\"UP\""]
#DECIMAL_TINY_DETECTION_AFTER_ROUNDING
rustflags=["--cfg", "default_rounding=\"TO_NEAREST\""]
rustdocflags=["--cfg", "default_rounding=\"TO_NEAREST\""]
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ edition = "2021"
[dependencies]

[features]
DECIMAL_TINY_DETECTION_AFTER_ROUNDING=[]
2,523 changes: 2,523 additions & 0 deletions src/bid128_add.rs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/bid128_fma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
/* Intel® Decimal Floating-Point Math Library - Copyright (c) 2018, Intel Corp. */
/* ----------------------------------------------------------------------------- */

#![allow(unused_assignments)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(unused_mut)]

#[cfg(target_endian = "big")]
use crate::bid_conf::BID_SWAP128;
Expand Down
4 changes: 4 additions & 0 deletions src/bid128_mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
/* Intel® Decimal Floating-Point Math Library - Copyright (c) 2018, Intel Corp. */
/* ----------------------------------------------------------------------------- */

#![allow(unused_assignments)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(unused_mut)]

#[cfg(target_endian = "big")]
use crate::bid_conf::BID_SWAP128;
Expand Down Expand Up @@ -240,8 +242,10 @@ pub (crate) fn bid128_mul(x: &BID_UINT128, y: &BID_UINT128, rnd_mode: u32, pfpsf
// x = 0 or y = 0
// the result is 0
let mut res = BID_UINT128 { w: [0x0, p_sign | p_exp] }; // preferred exponent in [EXP_MIN, EXP_MAX]

#[cfg(target_endian = "big")]
BID_SWAP128(&mut resres);

return res;
} // else continue
}
Expand Down
6 changes: 3 additions & 3 deletions src/bid128_noncomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,9 @@ pub (crate) fn bid128_isCanonical(x: &BID_UINT128) -> bool {
sig_x.w[0] = x.w[0];
// a canonical number has a coefficient < 10^34
// (0x0001ed09_bead87c0_378d8e64_00000000)
if (sig_x.w[1] > 0x0001ed09bead87c0u64) || // significand is non-canonical
((sig_x.w[1] == 0x0001ed09bead87c0u64) && (sig_x.w[0] > 0x378d8e63ffffffffu64)) || // significand is non-canonical
((x.w[1] & 0x6000000000000000u64) == 0x6000000000000000u64) {
if (sig_x.w[1] > 0x0001ed09bead87c0u64) || // significand is non-canonical
((sig_x.w[1] == 0x0001ed09bead87c0u64) && (sig_x.w[0] > 0x378d8e63ffffffffu64)) || // significand is non-canonical
((x.w[1] & 0x6000000000000000u64) == 0x6000000000000000u64) {
false
} else {
true
Expand Down
8 changes: 4 additions & 4 deletions src/bid_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,27 +234,27 @@ pub (crate) fn get_BID64(sgn: BID_UINT64, mut expon: i32, mut coeff: BID_UINT64,
&& (Q_low.w[1] < bid_reciprocals10_128[extra_digits as usize].w[1]
|| (Q_low.w[1] == bid_reciprocals10_128[extra_digits as usize].w[1]
&& Q_low.w[0] < bid_reciprocals10_128[extra_digits as usize].w[0])) {
status = BID_EXACT_STATUS;
status = StatusFlags::BID_EXACT_STATUS;
}
},
RoundingMode::BID_ROUNDING_DOWN | RoundingMode::BID_ROUNDING_TO_ZERO => { // test whether fractional part is 0
if remainder_h == 0
&& (Q_low.w[1] < bid_reciprocals10_128[extra_digits as usize].w[1]
|| (Q_low.w[1] == bid_reciprocals10_128[extra_digits as usize].w[1]
&& Q_low.w[0] < bid_reciprocals10_128[extra_digits as usize].w[0])) {
status = BID_EXACT_STATUS;
status = StatusFlags::BID_EXACT_STATUS;
}
},
_ => { // round up
(Stemp.w[0], CY) = __add_carry_out(Q_low.w[0], bid_reciprocals10_128[extra_digits as usize].w[0]);
(Stemp.w[1], carry) = __add_carry_in_out(Q_low.w[1], bid_reciprocals10_128[extra_digits as usize].w[1], CY);
if (remainder_h >> (64 - amount)) + carry >= ((1u64) << amount) {
status = BID_EXACT_STATUS;
status = StatusFlags::BID_EXACT_STATUS;
}
}
};

if status != BID_EXACT_STATUS {
if status != StatusFlags::BID_EXACT_STATUS {
__set_status_flags(fpsc, StatusFlags::BID_UNDERFLOW_EXCEPTION | status);
}
}
Expand Down
1 change: 0 additions & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ pub (crate) const BID32_MAXDIGITS: u32 = 7;
pub (crate) const BID_FLAG_MASK: u32 = 0x0000003f;
pub (crate) const DEC_FE_ALL_EXCEPT: u32 = 0x0000003f;
pub (crate) const BID_IEEE_FLAGS: u32 = 0x0000003d;
pub (crate) const BID_EXACT_STATUS:u32 = 0x00000000;

pub (crate) const DEC_FE_INVALID:u32 = 0x01;
pub (crate) const DEC_FE_UNNORMAL:u32 = 0x02;
Expand Down
8 changes: 4 additions & 4 deletions src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,15 @@ pub (crate) fn bid128_to_bid64(x: &BID_UINT128, rnd_mode: u32, pfpsf: &mut _IDEC
&& (Ql.w[1] < bid_reciprocals10_128[extra_digits as usize].w[1]
|| (Ql.w[1] == bid_reciprocals10_128[extra_digits as usize].w[1]
&& Ql.w[0] < bid_reciprocals10_128[extra_digits as usize].w[0])) {
status = BID_EXACT_STATUS;
status = StatusFlags::BID_EXACT_STATUS;
}
},
RoundingMode::BID_ROUNDING_DOWN | RoundingMode::BID_ROUNDING_TO_ZERO => {
if (Qh1.w[1] == 0) && (Qh1.w[0] == 0)
&& (Ql.w[1] < bid_reciprocals10_128[extra_digits as usize].w[1]
|| (Ql.w[1] == bid_reciprocals10_128[extra_digits as usize].w[1]
&& Ql.w[0] < bid_reciprocals10_128[extra_digits as usize].w[0])) {
status = BID_EXACT_STATUS;
status = StatusFlags::BID_EXACT_STATUS;
}
},
_ => {
Expand All @@ -228,12 +228,12 @@ pub (crate) fn bid128_to_bid64(x: &BID_UINT128, rnd_mode: u32, pfpsf: &mut _IDEC
Qh.w[1] += 1;
}
if __unsigned_compare_ge_128(Qh, Tmp1) {
status = BID_EXACT_STATUS;
status = StatusFlags::BID_EXACT_STATUS;
}
}
}

if status != BID_EXACT_STATUS {
if status != StatusFlags::BID_EXACT_STATUS {
if uf_check != 0 {
status |= StatusFlags::BID_UNDERFLOW_EXCEPTION;
}
Expand Down
1 change: 1 addition & 0 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ impl StatusFlags {
pub const BID_INVALID_EXCEPTION: _IDEC_flags = DEC_FE_INVALID;
pub const BID_UNDERFLOW_INEXACT_EXCEPTION: _IDEC_flags = DEC_FE_UNDERFLOW | DEC_FE_INEXACT;
pub const BID_OVERFLOW_INEXACT_EXCEPTION: _IDEC_flags = DEC_FE_OVERFLOW | DEC_FE_INEXACT;
pub const BID_EXACT_STATUS:_IDEC_flags = 0x00000000;
}
129 changes: 122 additions & 7 deletions src/dec128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]

use std::ops::{Mul, MulAssign, Neg};
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use crate::bid128_add::{bid128_add, bid128_sub};
use crate::bid128_mul::bid128_mul;

use crate::bid128_noncomp::*;
Expand Down Expand Up @@ -92,7 +93,7 @@ pub struct BID_UINT128 {
pub type decimal128 = BID_UINT128;

impl decimal128 {
pub (crate) fn new(l: u64, h: u64) -> Self {
pub (crate) fn new(h: u64, l: u64) -> Self {
#[cfg(target_endian = "big")]
return Self { w: [h, l] };

Expand Down Expand Up @@ -199,6 +200,14 @@ impl decimal128 {
pub fn multiply(lhs: &Self, rhs: &Self, rnd_mode: Option<u32>, status: &mut _IDEC_flags) -> Self {
bid128_mul(lhs, rhs, rnd_mode.unwrap_or(RoundingMode::BID_ROUNDING_UP), status)
}

pub fn add(lhs: &Self, rhs: &Self, rnd_mode: Option<u32>, status: &mut _IDEC_flags) -> Self {
bid128_add(lhs, rhs, rnd_mode.unwrap_or(RoundingMode::BID_ROUNDING_UP), status)
}

pub fn subtract(lhs: &Self, rhs: &Self, rnd_mode: Option<u32>, status: &mut _IDEC_flags) -> Self {
bid128_sub(lhs, rhs, rnd_mode.unwrap_or(RoundingMode::BID_ROUNDING_UP), status)
}
}

impl Eq for decimal128 {}
Expand Down Expand Up @@ -253,7 +262,7 @@ impl From<decimal64> for decimal128 {
/// ```
impl From<i128> for decimal128 {
fn from(value: i128) -> Self {
Self::new(value as u64, (value >> 64) as u64, )
Self::new((value >> 64) as u64, value as u64)
}
}

Expand All @@ -265,7 +274,7 @@ impl From<i128> for decimal128 {
/// ```
impl From<u128> for decimal128 {
fn from(value: u128) -> Self {
Self::new(value as u64, (value >> 64) as u64)
Self::new((value >> 64) as u64, value as u64, )
}
}

Expand All @@ -291,7 +300,7 @@ impl Neg for decimal128 {
/// ```
/// use std::ops::Neg;
/// let dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let neg = dec1.neg();
/// let neg = &dec1.neg();
/// ```
impl Neg for &decimal128 {
type Output = decimal128;
Expand All @@ -301,6 +310,59 @@ impl Neg for &decimal128 {
}
}

/// Performs the + operation.
/// # Examples
///
/// ```
/// let dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let dec2 = decmathlib_rs::dec128::decimal128::from(0xc47aef17e9919a5569aaaf503275e8f4u128);
/// let res = dec1 + dec2;
/// ```
impl Add for decimal128 {
type Output = Self;

fn add(self, rhs: Self) -> Self::Output {
let mut status: _IDEC_flags = 0;
bid128_add(&self, &rhs, DEFAULT_ROUNDING_MODE, &mut status)
}
}

/// Performs the + operation.
/// # Examples
///
/// ```
/// let dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let dec2 = decmathlib_rs::dec128::decimal128::from(0xc47aef17e9919a5569aaaf503275e8f4u128);
/// let res = &dec1 + &dec2;
/// ```
impl Add for &decimal128 {
type Output = decimal128;

fn add(self, rhs: Self) -> Self::Output {
let mut status: _IDEC_flags = 0;
bid128_add(self, rhs, DEFAULT_ROUNDING_MODE, &mut status)
}
}

/// Performs the += operation.
/// # Examples
///
/// ```
/// use decmathlib_rs::core::RoundingMode;
/// let mut dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let dec2 = decmathlib_rs::dec128::decimal128::from(0xc47aef17e9919a5569aaaf503275e8f4u128);
/// dec1 += dec2;
/// ```
impl AddAssign for decimal128 {
fn add_assign(&mut self, rhs: Self) {
let mut status: _IDEC_flags = 0;
let dec = bid128_mul(self, &rhs, DEFAULT_ROUNDING_MODE, &mut status);

self.w[0] = dec.w[0];
self.w[1] = dec.w[1];
}
}

/// Performs the * operation.
/// # Examples
///
Expand All @@ -324,7 +386,7 @@ impl Mul for decimal128 {
/// ```
/// let dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let dec2 = decmathlib_rs::dec128::decimal128::from(0xc47aef17e9919a5569aaaf503275e8f4u128);
/// let res = dec1 * dec2;
/// let res = &dec1 * &dec2;
/// ```
impl Mul for &decimal128 {
type Output = decimal128;
Expand Down Expand Up @@ -352,4 +414,57 @@ impl MulAssign for decimal128 {
self.w[0] = dec.w[0];
self.w[1] = dec.w[1];
}
}
}

/// Performs the - operation.
/// # Examples
///
/// ```
/// let dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let dec2 = decmathlib_rs::dec128::decimal128::from(0xc47aef17e9919a5569aaaf503275e8f4u128);
/// let res = dec1 - dec2;
/// ```
impl Sub for decimal128 {
type Output = Self;

fn sub(self, rhs: Self) -> Self::Output {
let mut status: _IDEC_flags = 0;
bid128_sub(&self, &rhs, DEFAULT_ROUNDING_MODE, &mut status)
}
}

/// Performs the - operation.
/// # Examples
///
/// ```
/// let dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let dec2 = decmathlib_rs::dec128::decimal128::from(0xc47aef17e9919a5569aaaf503275e8f4u128);
/// let res = &dec1 - &dec2;
/// ```
impl Sub for &decimal128 {
type Output = decimal128;

fn sub(self, rhs: Self) -> Self::Output {
let mut status: _IDEC_flags = 0;
bid128_sub(self, rhs, DEFAULT_ROUNDING_MODE, &mut status)
}
}

/// Performs the *= operation.
/// # Examples
///
/// ```
/// use decmathlib_rs::core::RoundingMode;
/// let mut dec1 = decmathlib_rs::dec128::decimal128::from(0x150a2e0d6728de4e95595bd43d654036u128);
/// let dec2 = decmathlib_rs::dec128::decimal128::from(0xc47aef17e9919a5569aaaf503275e8f4u128);
/// dec1 += dec2;
/// ```
impl SubAssign for decimal128 {
fn sub_assign(&mut self, rhs: Self) {
let mut status: _IDEC_flags = 0;
let dec = bid128_sub(self, &rhs, DEFAULT_ROUNDING_MODE, &mut status);

self.w[0] = dec.w[0];
self.w[1] = dec.w[1];
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/* --------------------------------------------------------------------- */

mod bid128;
mod bid128_add;
mod bid128_fma;
mod bid128_mul;
mod bid128_noncomp;
Expand Down
Loading

0 comments on commit b41601b

Please sign in to comment.