Skip to content

Commit 2d6a431

Browse files
committed
arrow-buffer: implement num-traits numeric operations
1 parent a67cd19 commit 2d6a431

File tree

1 file changed

+119
-1
lines changed

1 file changed

+119
-1
lines changed

arrow-buffer/src/bigint/mod.rs

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
use crate::arith::derive_arith;
1919
use crate::bigint::div::div_rem;
2020
use num_bigint::BigInt;
21-
use num_traits::{FromPrimitive, ToPrimitive, cast::AsPrimitive};
21+
use num_traits::{
22+
cast::AsPrimitive, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedSub, FromPrimitive,
23+
Num, One, Signed, ToPrimitive, Zero,
24+
};
2225
use std::cmp::Ordering;
2326
use std::num::ParseIntError;
2427
use std::ops::{BitAnd, BitOr, BitXor, Neg, Shl, Shr};
@@ -860,6 +863,103 @@ impl ToPrimitive for i256 {
860863
}
861864
}
862865

866+
// num_traits checked implementations
867+
868+
impl CheckedNeg for i256 {
869+
fn checked_neg(&self) -> Option<Self> {
870+
(*self).checked_neg()
871+
}
872+
}
873+
874+
impl CheckedAdd for i256 {
875+
fn checked_add(&self, v: &i256) -> Option<Self> {
876+
(*self).checked_add(*v)
877+
}
878+
}
879+
880+
impl CheckedSub for i256 {
881+
fn checked_sub(&self, v: &i256) -> Option<Self> {
882+
(*self).checked_sub(*v)
883+
}
884+
}
885+
886+
impl CheckedDiv for i256 {
887+
fn checked_div(&self, v: &i256) -> Option<Self> {
888+
(*self).checked_sub(*v)
889+
}
890+
}
891+
892+
impl CheckedMul for i256 {
893+
fn checked_mul(&self, v: &i256) -> Option<Self> {
894+
(*self).checked_mul(*v)
895+
}
896+
}
897+
898+
impl CheckedRem for i256 {
899+
fn checked_rem(&self, v: &i256) -> Option<Self> {
900+
(*self).checked_rem(*v)
901+
}
902+
}
903+
904+
impl Zero for i256 {
905+
fn zero() -> Self {
906+
i256::ZERO
907+
}
908+
909+
fn is_zero(&self) -> bool {
910+
*self == i256::ZERO
911+
}
912+
}
913+
914+
impl One for i256 {
915+
fn one() -> Self {
916+
i256::ONE
917+
}
918+
919+
fn is_one(&self) -> bool {
920+
*self == i256::ONE
921+
}
922+
}
923+
924+
impl Num for i256 {
925+
type FromStrRadixErr = ParseI256Error;
926+
927+
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
928+
if radix == 10 {
929+
str.parse()
930+
} else {
931+
// Parsing from non-10 baseseeÎ is not supported
932+
Err(ParseI256Error {})
933+
}
934+
}
935+
}
936+
937+
impl Signed for i256 {
938+
fn abs(&self) -> Self {
939+
self.wrapping_abs()
940+
}
941+
942+
fn abs_sub(&self, other: &Self) -> Self {
943+
if self > other {
944+
self.wrapping_sub(*other)
945+
} else {
946+
i256::ZERO
947+
}
948+
}
949+
950+
fn signum(&self) -> Self {
951+
(*self).signum()
952+
}
953+
954+
fn is_positive(&self) -> bool {
955+
(*self).is_positive()
956+
}
957+
958+
fn is_negative(&self) -> bool {
959+
(*self).is_negative()
960+
}
961+
}
962+
863963
#[cfg(all(test, not(miri)))] // llvm.x86.subborrow.64 not supported by MIRI
864964
mod tests {
865965
use super::*;
@@ -1327,4 +1427,22 @@ mod tests {
13271427
let out = big_neg.to_f64().unwrap();
13281428
assert!(out.is_finite() && out.is_sign_negative());
13291429
}
1430+
1431+
#[test]
1432+
fn test_num_traits() {
1433+
let value = i256::from_i128(-5);
1434+
assert_eq!(
1435+
<i256 as CheckedNeg>::checked_neg(&value),
1436+
Some(i256::from_i128(5))
1437+
);
1438+
1439+
assert_eq!(
1440+
<i256 as CheckedAdd>::checked_add(&value, &value),
1441+
Some(i256::from_i128(-10))
1442+
);
1443+
1444+
assert_eq!(<i256 as Signed>::abs(&value), i256::from_i128(5));
1445+
1446+
assert_eq!(<i256 as One>::one(), i256::from_i128(1));
1447+
}
13301448
}

0 commit comments

Comments
 (0)