Skip to content
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
1,399 changes: 0 additions & 1,399 deletions arbi/src/add.rs

This file was deleted.

53 changes: 52 additions & 1 deletion arbi/src/comparisons.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/*
Copyright 2024 Owain Davies
Copyright 2024-2025 Owain Davies
SPDX-License-Identifier: Apache-2.0 OR MIT
*/

use crate::Arbi;
use crate::Digit;
use core::cmp::Ordering;

impl Ord for Arbi {
Expand All @@ -26,6 +27,56 @@ impl PartialEq for Arbi {

impl Eq for Arbi {}

#[inline(always)]
pub(crate) fn s_size(digits: &[Digit]) -> usize {
let mut len = digits.len();
while len > 0 && digits[len - 1] == 0 {
len -= 1;
}
len
}

pub(crate) fn s_cmp_impl(
a: &[Digit],
b: &[Digit],
assume_normalized: bool,
) -> Ordering {
let (a_size, b_size) = if assume_normalized {
(a.len(), b.len())
} else {
(s_size(a), s_size(b))
};
match a_size.cmp(&b_size) {
Ordering::Equal => {
for i in (0..a_size).rev() {
match a[i].cmp(&b[i]) {
Ordering::Equal => continue,
other => return other,
}
}
Ordering::Equal
}
other => other,
}
}

#[allow(dead_code)]
pub(crate) fn s_cmp(a: &[Digit], b: &[Digit]) -> Ordering {
s_cmp_impl(a, b, false)
}

pub(crate) fn s_cmp_normalized(a: &[Digit], b: &[Digit]) -> Ordering {
debug_assert!(
a.is_empty() || a.last() != Some(&0),
"slice a not normalized"
);
debug_assert!(
b.is_empty() || b.last() != Some(&0),
"slice b not normalized"
);
s_cmp_impl(a, b, true)
}

impl Arbi {
// Assumes x, y >= 0
pub(crate) fn cmp_abs(x: &Self, y: &Self) -> Ordering {
Expand Down
12 changes: 8 additions & 4 deletions arbi/src/division.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/*
Copyright 2024 Owain Davies
Copyright 2024-2025 Owain Davies
SPDX-License-Identifier: Apache-2.0 OR MIT
*/

use crate::util::to_digits::{length_digits, ToDigits};
use crate::util::ArbiLikeView;
use crate::{Arbi, BitCount, DDigit, Digit, SDDigit};
use core::ops::{Div, DivAssign, Rem, RemAssign};

Expand Down Expand Up @@ -72,8 +73,8 @@ impl Arbi {
if Arbi::cmp_abs(r, v) != core::cmp::Ordering::Less {
// (3)(III)(a)
// *r = &(*r) - v;
Arbi::sub_abs_inplace(r, v, false);
// (3)(III)(b)
r.isub_with_arbi_like_view(v.into()); // previously, Arbi::sub_abs_inplace(r, v, false); r = |r| - |v|
// (3)(III)(b)
q.set_bit(i);
}
}
Expand Down Expand Up @@ -265,7 +266,10 @@ impl Arbi {
q.negate_mut();
*q -= 1;
r.negate_mut();
r.dadd_inplace(d, d_sign == -1); // *r += d;
r.iadd_with_arbi_like_view(ArbiLikeView {
vec: d,
neg: d_sign == -1,
}); // *r += d;
}
}
_ => {}
Expand Down
1 change: 0 additions & 1 deletion arbi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ extern crate test;

use alloc::vec::Vec;

mod add;
mod assign;
mod assign_double;
mod assign_integral;
Expand Down
268 changes: 268 additions & 0 deletions arbi/src/ops/add/arbi_x_arbi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/*
Copyright 2025 Owain Davies
SPDX-License-Identifier: Apache-2.0 OR MIT
*/

use crate::Arbi;
use core::ops::{Add, AddAssign, Sub, SubAssign};

/// `a += &b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let mut a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// a += &b;
/// assert_eq!(a, -1358023);
/// ```
impl<'a> AddAssign<&'a Arbi> for Arbi {
fn add_assign(&mut self, other: &'a Arbi) {
self.iadd(other);
}
}

/// `a += b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let mut a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// a += b;
/// assert_eq!(a, -1358023);
/// ```
impl AddAssign<Arbi> for Arbi {
fn add_assign(&mut self, mut other: Self) {
if other.capacity() > self.capacity() {
core::mem::swap(self, &mut other);
}
*self += &other;
}
}

/// `a + b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// let c = a + b;
/// assert_eq!(c, -1358023);
/// ```
impl Add<Arbi> for Arbi {
type Output = Self;
fn add(mut self, other: Self) -> Self {
self += other;
self
}
}

/// `a + &b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// let c = a + &b;
/// assert_eq!(c, -1358023);
/// ```
impl<'a> Add<&'a Arbi> for Arbi {
type Output = Self;
fn add(mut self, other: &'a Arbi) -> Self {
self += other;
self
}
}

/// `&a + b`
///
/// # Examples
/// ```
/// use arbi::{Arbi, Digit};
///
/// let a = Arbi::from(-123456);
/// let b = Arbi::from(1234567);
/// let b_cap = b.capacity();
/// let c = &a + b; // In this case, no memory allocation (b's memory is
/// // used.
/// assert_eq!(c, 1111111);
/// assert_eq!(c.capacity(), b_cap);
///
/// let a = Arbi::from(-(Digit::MAX as i128));
/// let b = Arbi::from(-1234567);
/// let b_cap = b.capacity();
/// let c = &a + b; // In this case, memory allocation may or may not occur,
/// // depending on b's capacity.
/// assert!(c.capacity() >= b_cap);
/// ```
impl Add<Arbi> for &Arbi {
type Output = Arbi;
fn add(self, mut other: Arbi) -> Arbi {
other += self;
other
}
}

/// `&a + &b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// let c = &a + &b;
/// assert_eq!(c, -1358023);
/// ```
impl<'b> Add<&'b Arbi> for &Arbi {
type Output = Arbi;
fn add(self, other: &'b Arbi) -> Arbi {
let mut ret;
if self.size() <= other.size() {
ret = Arbi::with_capacity_and_copy(other.size() + 1, other);
ret += self;
} else {
ret = Arbi::with_capacity_and_copy(self.size() + 1, self);
ret += other;
}
ret
}
}

/// `a -= &b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let mut a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// a -= &b;
/// assert_eq!(a, -1111111);
/// ```
impl<'a> SubAssign<&'a Arbi> for Arbi {
fn sub_assign(&mut self, other: &'a Arbi) {
self.isub(other);
}
}

/// `a -= b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let mut a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// a -= b;
/// assert_eq!(a, -1111111);
/// ```
impl SubAssign for Arbi {
fn sub_assign(&mut self, mut other: Self) {
if self.capacity() >= other.capacity() {
*self -= &other;
} else {
// -(other - self) = self - other
core::mem::swap(self, &mut other);
*self -= &other;
self.negate_mut();
}
}
}

/// `a - b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let a = Arbi::from(-1234567);
/// let a_cap = a.capacity();
/// let b = Arbi::from(-123456);
/// let c = a - b; // no memory allocation
/// assert_eq!(c, -1111111);
/// assert_eq!(c.capacity(), a_cap);
/// ```
impl Sub<Arbi> for Arbi {
type Output = Self;
fn sub(mut self, other: Self) -> Self {
self -= other;
self
}
}

/// `a - &b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let a = Arbi::from(-1234567);
/// let a_cap = a.capacity();
/// let b = Arbi::from(-123456);
/// let c = a - &b; // no memory allocation
/// assert_eq!(c, -1111111);
/// assert_eq!(c.capacity(), a_cap);
/// ```
impl<'a> Sub<&'a Arbi> for Arbi {
type Output = Self;
fn sub(mut self, other: &'a Arbi) -> Self {
self -= other;
self
}
}

/// `&a - b`
///
/// # Examples
/// ```
/// use arbi::{Arbi, Digit};
///
/// let a = Arbi::from(1234567);
/// let b = Arbi::from(123456);
/// let b_cap = b.capacity();
/// let c = &a - b; // In this case, no memory allocation (b's memory is
/// // used.
/// assert_eq!(c, 1111111);
/// assert_eq!(c.capacity(), b_cap);
///
/// let a = Arbi::from(-(Digit::MAX as i128));
/// let b = Arbi::from(-1234567);
/// let b_cap = b.capacity();
/// let c = &a - b; // In this case, no memory allocation
/// assert_eq!(c.capacity(), b_cap);
/// ```
impl Sub<Arbi> for &Arbi {
type Output = Arbi;
fn sub(self, mut other: Arbi) -> Arbi {
// a - b = -(b - a)
other -= self;
other.negate_mut();
other
}
}

/// `&a - &b`
///
/// # Examples
/// ```
/// use arbi::Arbi;
/// let a = Arbi::from(-1234567);
/// let b = Arbi::from(-123456);
/// let c = &a - &b; // memory allocation
/// assert_eq!(c, -1111111);
/// ```
impl<'b> Sub<&'b Arbi> for &Arbi {
type Output = Arbi;
fn sub(self, other: &'b Arbi) -> Arbi {
let mut ret;
if self.size() <= other.size() {
// -(other - self) = self - other
ret = Arbi::with_capacity_and_copy(other.size(), other);
ret -= self;
ret.negate_mut();
} else {
ret = Arbi::with_capacity_and_copy(self.size(), self);
ret -= other;
}
ret
}
}
Loading
Loading