Skip to content

Commit

Permalink
BigInt to u128.
Browse files Browse the repository at this point in the history
  • Loading branch information
oskin1 committed Jan 8, 2024
1 parent 06c03cc commit 63a743d
Showing 1 changed file with 38 additions and 2 deletions.
40 changes: 38 additions & 2 deletions chain/rust/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,23 @@ impl BigInt {
}
}

/// Converts to a u128
/// Returns None if the number was negative or too big for a u128
pub fn as_u128(&self) -> Option<u128> {
let (sign, u32_digits) = self.num.to_u32_digits();
if sign == num_bigint::Sign::Minus {
return None;
}
match *u32_digits {
[] => Some(0),
[a] => Some(u128::from(a)),
[a, b] => Some(u128::from(b) | (u128::from(a) << 32)),
[a, b, c] => Some(u128::from(c) | (u128::from(b) << 32) | (u128::from(a) << 64)),
[a, b, c, d] => Some(u128::from(d) | (u128::from(c) << 32) | (u128::from(b) << 64) | (u128::from(a) << 96)),
_ => None,
}
}

/// Converts to an Int
/// Returns None when the number is too big for an Int (outside +/- 64-bit unsigned)
/// Retains encoding info if the original was encoded as an Int
Expand Down Expand Up @@ -548,10 +565,11 @@ impl Deserialize for NetworkId {

#[cfg(test)]
mod tests {
use std::str::FromStr;
use super::*;

#[test]
fn bigint_uint_min() {
fn bigint_uint_u64_min() {
let bytes = [0x00];
let x = BigInt::from_cbor_bytes(&bytes).unwrap();
assert_eq!(bytes, x.to_cbor_bytes().as_slice());
Expand All @@ -561,7 +579,7 @@ mod tests {
}

#[test]
fn bigint_uint_max() {
fn bigint_uint_u64_max() {
let bytes = [0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
let x = BigInt::from_cbor_bytes(&bytes).unwrap();
assert_eq!(bytes, x.to_cbor_bytes().as_slice());
Expand All @@ -570,6 +588,24 @@ mod tests {
assert_eq!(x.to_string(), "18446744073709551615");
}

#[test]
fn bigint_uint_u128_min() {
let bytes = [0x00];
let x = BigInt::from_cbor_bytes(&bytes).unwrap();
assert_eq!(bytes, x.to_cbor_bytes().as_slice());
assert_eq!(x.as_u128(), Some(u128::MIN));
assert_eq!(x.to_string(), "0");
}

#[test]
fn bigint_uint_u128_max() {
let bytes = BigInt::from_str(&*u128::MAX.to_string()).unwrap().to_cbor_bytes();
let x = BigInt::from_cbor_bytes(&bytes).unwrap();
assert_eq!(bytes, x.to_cbor_bytes().as_slice());
assert_eq!(x.as_u128(), Some(u128::MAX));
assert_eq!(x.to_string(), "340282366920938463463374607431768211455");
}

#[test]
fn bigint_above_uint_min() {
let bytes = [
Expand Down

0 comments on commit 63a743d

Please sign in to comment.