1use alloc::string::{String, ToString};
2use core::fmt;
3use core::ops::{
4 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr,
5 ShrAssign, Sub, SubAssign,
6};
7use core::str::FromStr;
8
9use crate::errors::{
10 ConversionOverflowError, DivideByZeroError, ErrorKind, OverflowError, OverflowOperation,
11 StdError,
12};
13use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
14use crate::{
15 Int128, Int256, Int512, Int64, Uint128, Uint256, Uint64, __internal::forward_ref_partial_eq,
16};
17
18use bnum::types::U512;
21
22use super::conversion::{forward_try_from, primitive_to_wrapped_int, try_from_int_to_uint};
23use super::impl_int_serde;
24use super::num_consts::NumConsts;
25
26#[derive(
53 Copy,
54 Clone,
55 Default,
56 Debug,
57 PartialEq,
58 Eq,
59 PartialOrd,
60 Ord,
61 schemars::JsonSchema,
62 cw_schema::Schemaifier,
63)]
64#[schemaifier(type = cw_schema::NodeType::Integer { precision: 512, signed: false })]
65pub struct Uint512(#[schemars(with = "String")] pub(crate) U512);
66
67impl_int_serde!(Uint512);
68forward_ref_partial_eq!(Uint512, Uint512);
69
70impl Uint512 {
71 pub const MAX: Uint512 = Uint512(U512::MAX);
72 pub const MIN: Uint512 = Uint512(U512::ZERO);
73
74 #[must_use]
83 pub const fn new(value: u128) -> Self {
84 let b = value.to_be_bytes();
85 Self::from_be_bytes([
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b[0], b[1], b[2], b[3], b[4],
88 b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15],
89 ])
90 }
91
92 #[inline]
94 pub const fn zero() -> Self {
95 Uint512(U512::ZERO)
96 }
97
98 #[inline]
100 pub const fn one() -> Self {
101 Self(U512::ONE)
102 }
103
104 #[must_use]
105 pub const fn from_be_bytes(data: [u8; 64]) -> Self {
106 let words: [u64; 8] = [
107 u64::from_le_bytes([
108 data[63], data[62], data[61], data[60], data[59], data[58], data[57], data[56],
109 ]),
110 u64::from_le_bytes([
111 data[55], data[54], data[53], data[52], data[51], data[50], data[49], data[48],
112 ]),
113 u64::from_le_bytes([
114 data[47], data[46], data[45], data[44], data[43], data[42], data[41], data[40],
115 ]),
116 u64::from_le_bytes([
117 data[39], data[38], data[37], data[36], data[35], data[34], data[33], data[32],
118 ]),
119 u64::from_le_bytes([
120 data[31], data[30], data[29], data[28], data[27], data[26], data[25], data[24],
121 ]),
122 u64::from_le_bytes([
123 data[23], data[22], data[21], data[20], data[19], data[18], data[17], data[16],
124 ]),
125 u64::from_le_bytes([
126 data[15], data[14], data[13], data[12], data[11], data[10], data[9], data[8],
127 ]),
128 u64::from_le_bytes([
129 data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0],
130 ]),
131 ];
132 Self(U512::from_digits(words))
133 }
134
135 #[must_use]
136 pub const fn from_le_bytes(data: [u8; 64]) -> Self {
137 let words: [u64; 8] = [
138 u64::from_le_bytes([
139 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
140 ]),
141 u64::from_le_bytes([
142 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
143 ]),
144 u64::from_le_bytes([
145 data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23],
146 ]),
147 u64::from_le_bytes([
148 data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31],
149 ]),
150 u64::from_le_bytes([
151 data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39],
152 ]),
153 u64::from_le_bytes([
154 data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47],
155 ]),
156 u64::from_le_bytes([
157 data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55],
158 ]),
159 u64::from_le_bytes([
160 data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63],
161 ]),
162 ];
163 Self(U512::from_digits(words))
164 }
165
166 #[must_use]
169 pub const fn from_uint256(num: Uint256) -> Self {
170 let bytes = num.to_le_bytes();
171 Self::from_le_bytes([
172 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
173 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
174 bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23],
175 bytes[24], bytes[25], bytes[26], bytes[27], bytes[28], bytes[29], bytes[30], bytes[31],
176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177 0, 0, 0,
178 ])
179 }
180
181 #[must_use = "this returns the result of the operation, without modifying the original"]
183 pub const fn to_be_bytes(self) -> [u8; 64] {
184 let words = self.0.digits();
185 let words = [
186 words[7].to_be_bytes(),
187 words[6].to_be_bytes(),
188 words[5].to_be_bytes(),
189 words[4].to_be_bytes(),
190 words[3].to_be_bytes(),
191 words[2].to_be_bytes(),
192 words[1].to_be_bytes(),
193 words[0].to_be_bytes(),
194 ];
195 unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) }
196 }
197
198 #[must_use = "this returns the result of the operation, without modifying the original"]
200 pub const fn to_le_bytes(self) -> [u8; 64] {
201 let words = self.0.digits();
202 let words = [
203 words[0].to_le_bytes(),
204 words[1].to_le_bytes(),
205 words[2].to_le_bytes(),
206 words[3].to_le_bytes(),
207 words[4].to_le_bytes(),
208 words[5].to_le_bytes(),
209 words[6].to_le_bytes(),
210 words[7].to_le_bytes(),
211 ];
212 unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) }
213 }
214
215 #[must_use]
216 pub const fn is_zero(&self) -> bool {
217 self.0.is_zero()
218 }
219
220 #[must_use = "this returns the result of the operation, without modifying the original"]
221 pub const fn pow(self, exp: u32) -> Self {
222 match self.0.checked_pow(exp) {
223 Some(val) => Self(val),
224 None => panic!("attempt to exponentiate with overflow"),
225 }
226 }
227
228 #[must_use = "this returns the result of the operation, without modifying the original"]
234 pub fn ilog2(self) -> u32 {
235 self.0.checked_ilog2().unwrap()
236 }
237
238 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
239 self.0
240 .checked_add(other.0)
241 .map(Self)
242 .ok_or_else(|| OverflowError::new(OverflowOperation::Add))
243 }
244
245 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
246 self.0
247 .checked_sub(other.0)
248 .map(Self)
249 .ok_or_else(|| OverflowError::new(OverflowOperation::Sub))
250 }
251
252 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
253 self.0
254 .checked_mul(other.0)
255 .map(Self)
256 .ok_or_else(|| OverflowError::new(OverflowOperation::Mul))
257 }
258
259 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
260 self.0
261 .checked_pow(exp)
262 .map(Self)
263 .ok_or_else(|| OverflowError::new(OverflowOperation::Pow))
264 }
265
266 pub fn checked_div(self, other: Self) -> Result<Self, DivideByZeroError> {
267 self.0
268 .checked_div(other.0)
269 .map(Self)
270 .ok_or(DivideByZeroError)
271 }
272
273 pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivideByZeroError> {
274 self.checked_div(other)
275 }
276
277 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
278 self.0
279 .checked_rem(other.0)
280 .map(Self)
281 .ok_or(DivideByZeroError)
282 }
283
284 pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
285 self.0
286 .checked_shr(other)
287 .map(Self)
288 .ok_or_else(|| OverflowError::new(OverflowOperation::Shr))
289 }
290
291 pub fn checked_shl(self, other: u32) -> Result<Self, OverflowError> {
292 if other >= 512 {
293 return Err(OverflowError::new(OverflowOperation::Shl));
294 }
295
296 Ok(Self(self.0.shl(other)))
297 }
298
299 #[must_use = "this returns the result of the operation, without modifying the original"]
300 #[inline]
301 pub fn wrapping_add(self, other: Self) -> Self {
302 Self(self.0.wrapping_add(other.0))
303 }
304
305 #[must_use = "this returns the result of the operation, without modifying the original"]
306 #[inline]
307 pub fn wrapping_sub(self, other: Self) -> Self {
308 Self(self.0.wrapping_sub(other.0))
309 }
310
311 #[must_use = "this returns the result of the operation, without modifying the original"]
312 #[inline]
313 pub fn wrapping_mul(self, other: Self) -> Self {
314 Self(self.0.wrapping_mul(other.0))
315 }
316
317 #[must_use = "this returns the result of the operation, without modifying the original"]
318 #[inline]
319 pub fn wrapping_pow(self, other: u32) -> Self {
320 Self(self.0.wrapping_pow(other))
321 }
322
323 #[must_use = "this returns the result of the operation, without modifying the original"]
324 pub fn saturating_add(self, other: Self) -> Self {
325 Self(self.0.saturating_add(other.0))
326 }
327
328 #[must_use = "this returns the result of the operation, without modifying the original"]
329 pub fn saturating_sub(self, other: Self) -> Self {
330 Self(self.0.saturating_sub(other.0))
331 }
332
333 #[must_use = "this returns the result of the operation, without modifying the original"]
334 pub fn saturating_mul(self, other: Self) -> Self {
335 Self(self.0.saturating_mul(other.0))
336 }
337
338 #[must_use = "this returns the result of the operation, without modifying the original"]
339 pub fn saturating_pow(self, exp: u32) -> Self {
340 Self(self.0.saturating_pow(exp))
341 }
342
343 #[must_use = "this returns the result of the operation, without modifying the original"]
347 pub const fn strict_add(self, rhs: Self) -> Self {
348 match self.0.checked_add(rhs.0) {
349 None => panic!("attempt to add with overflow"),
350 Some(sum) => Self(sum),
351 }
352 }
353
354 #[must_use = "this returns the result of the operation, without modifying the original"]
358 pub const fn strict_sub(self, other: Self) -> Self {
359 match self.0.checked_sub(other.0) {
360 None => panic!("attempt to subtract with overflow"),
361 Some(diff) => Self(diff),
362 }
363 }
364
365 #[must_use = "this returns the result of the operation, without modifying the original"]
366 pub const fn abs_diff(self, other: Self) -> Self {
367 Self(self.0.abs_diff(other.0))
368 }
369}
370
371impl NumConsts for Uint512 {
372 const ZERO: Self = Self::zero();
373 const ONE: Self = Self::one();
374 const MAX: Self = Self::MAX;
375 const MIN: Self = Self::MIN;
376}
377
378primitive_to_wrapped_int!(u8, Uint512);
380primitive_to_wrapped_int!(u16, Uint512);
381primitive_to_wrapped_int!(u32, Uint512);
382primitive_to_wrapped_int!(u64, Uint512);
383primitive_to_wrapped_int!(u128, Uint512);
384
385impl From<Uint256> for Uint512 {
386 fn from(val: Uint256) -> Self {
387 let mut bytes = [0u8; 64];
388 bytes[32..].copy_from_slice(&val.to_be_bytes());
389
390 Self::from_be_bytes(bytes)
391 }
392}
393
394impl From<Uint128> for Uint512 {
395 fn from(val: Uint128) -> Self {
396 val.u128().into()
397 }
398}
399
400impl From<Uint64> for Uint512 {
401 fn from(val: Uint64) -> Self {
402 val.u64().into()
403 }
404}
405
406impl TryFrom<Uint512> for Uint256 {
407 type Error = ConversionOverflowError;
408
409 fn try_from(value: Uint512) -> Result<Self, Self::Error> {
410 let bytes = value.to_be_bytes();
411 let (first_bytes, last_bytes) = bytes.split_at(32);
412
413 if first_bytes != [0u8; 32] {
414 return Err(ConversionOverflowError::new("Uint512", "Uint256"));
415 }
416
417 Ok(Self::from_be_bytes(last_bytes.try_into().unwrap()))
418 }
419}
420
421forward_try_from!(Uint512, Uint128);
422forward_try_from!(Uint512, Uint64);
423
424try_from_int_to_uint!(Int64, Uint512);
426try_from_int_to_uint!(Int128, Uint512);
427try_from_int_to_uint!(Int256, Uint512);
428try_from_int_to_uint!(Int512, Uint512);
429
430impl TryFrom<&str> for Uint512 {
431 type Error = StdError;
432
433 fn try_from(val: &str) -> Result<Self, Self::Error> {
434 Self::from_str(val)
435 }
436}
437
438impl FromStr for Uint512 {
439 type Err = StdError;
440
441 fn from_str(s: &str) -> Result<Self, Self::Err> {
442 match U512::from_str_radix(s, 10) {
443 Ok(u) => Ok(Self(u)),
444 Err(e) => {
445 Err(StdError::msg(format_args!("Parsing u512: {e}")).with_kind(ErrorKind::Parsing))
446 }
447 }
448 }
449}
450
451impl From<Uint512> for String {
452 fn from(original: Uint512) -> Self {
453 original.to_string()
454 }
455}
456
457impl fmt::Display for Uint512 {
458 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
459 self.0.fmt(f)
460 }
461}
462
463impl Add<Uint512> for Uint512 {
464 type Output = Self;
465
466 fn add(self, rhs: Self) -> Self {
467 self.strict_add(rhs)
468 }
469}
470forward_ref_binop!(impl Add, add for Uint512, Uint512);
471
472impl Sub<Uint512> for Uint512 {
473 type Output = Self;
474
475 fn sub(self, rhs: Self) -> Self {
476 self.strict_sub(rhs)
477 }
478}
479forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
480
481impl SubAssign<Uint512> for Uint512 {
482 fn sub_assign(&mut self, rhs: Uint512) {
483 self.0 = self.0.checked_sub(rhs.0).unwrap();
484 }
485}
486forward_ref_op_assign!(impl SubAssign, sub_assign for Uint512, Uint512);
487
488impl Div<Uint512> for Uint512 {
489 type Output = Self;
490
491 fn div(self, rhs: Self) -> Self::Output {
492 Self(self.0.checked_div(rhs.0).unwrap())
493 }
494}
495
496impl<'a> Div<&'a Uint512> for Uint512 {
497 type Output = Self;
498
499 fn div(self, rhs: &'a Uint512) -> Self::Output {
500 Self(self.0.checked_div(rhs.0).unwrap())
501 }
502}
503
504impl Rem for Uint512 {
505 type Output = Self;
506
507 #[inline]
511 fn rem(self, rhs: Self) -> Self {
512 Self(self.0.rem(rhs.0))
513 }
514}
515forward_ref_binop!(impl Rem, rem for Uint512, Uint512);
516
517impl Not for Uint512 {
518 type Output = Self;
519
520 fn not(self) -> Self::Output {
521 Self(!self.0)
522 }
523}
524
525impl RemAssign<Uint512> for Uint512 {
526 fn rem_assign(&mut self, rhs: Uint512) {
527 *self = *self % rhs;
528 }
529}
530forward_ref_op_assign!(impl RemAssign, rem_assign for Uint512, Uint512);
531
532impl Mul<Uint512> for Uint512 {
533 type Output = Self;
534
535 fn mul(self, rhs: Self) -> Self::Output {
536 Self(self.0.checked_mul(rhs.0).unwrap())
537 }
538}
539forward_ref_binop!(impl Mul, mul for Uint512, Uint512);
540
541impl MulAssign<Uint512> for Uint512 {
542 fn mul_assign(&mut self, rhs: Self) {
543 self.0 = self.0.checked_mul(rhs.0).unwrap();
544 }
545}
546forward_ref_op_assign!(impl MulAssign, mul_assign for Uint512, Uint512);
547
548impl Shr<u32> for Uint512 {
549 type Output = Self;
550
551 fn shr(self, rhs: u32) -> Self::Output {
552 self.checked_shr(rhs).unwrap_or_else(|_| {
553 panic!(
554 "right shift error: {rhs} is larger or equal than the number of bits in Uint512",
555 )
556 })
557 }
558}
559
560impl<'a> Shr<&'a u32> for Uint512 {
561 type Output = Self;
562
563 fn shr(self, rhs: &'a u32) -> Self::Output {
564 Shr::<u32>::shr(self, *rhs)
565 }
566}
567
568impl Shl<u32> for Uint512 {
569 type Output = Self;
570
571 fn shl(self, rhs: u32) -> Self::Output {
572 self.checked_shl(rhs)
573 .expect("attempt to shift left with overflow")
574 }
575}
576
577impl<'a> Shl<&'a u32> for Uint512 {
578 type Output = Self;
579
580 fn shl(self, rhs: &'a u32) -> Self::Output {
581 self.shl(*rhs)
582 }
583}
584
585impl AddAssign<Uint512> for Uint512 {
586 fn add_assign(&mut self, rhs: Uint512) {
587 self.0 = self.0.checked_add(rhs.0).unwrap();
588 }
589}
590
591impl<'a> AddAssign<&'a Uint512> for Uint512 {
592 fn add_assign(&mut self, rhs: &'a Uint512) {
593 self.0 = self.0.checked_add(rhs.0).unwrap();
594 }
595}
596
597impl DivAssign<Uint512> for Uint512 {
598 fn div_assign(&mut self, rhs: Self) {
599 self.0 = self.0.checked_div(rhs.0).unwrap();
600 }
601}
602
603impl<'a> DivAssign<&'a Uint512> for Uint512 {
604 fn div_assign(&mut self, rhs: &'a Uint512) {
605 self.0 = self.0.checked_div(rhs.0).unwrap();
606 }
607}
608
609impl ShrAssign<u32> for Uint512 {
610 fn shr_assign(&mut self, rhs: u32) {
611 *self = Shr::<u32>::shr(*self, rhs);
612 }
613}
614
615impl<'a> ShrAssign<&'a u32> for Uint512 {
616 fn shr_assign(&mut self, rhs: &'a u32) {
617 *self = Shr::<u32>::shr(*self, *rhs);
618 }
619}
620
621impl ShlAssign<u32> for Uint512 {
622 fn shl_assign(&mut self, rhs: u32) {
623 *self = self.shl(rhs);
624 }
625}
626
627impl<'a> ShlAssign<&'a u32> for Uint512 {
628 fn shl_assign(&mut self, rhs: &'a u32) {
629 *self = self.shl(*rhs);
630 }
631}
632
633impl<A> core::iter::Sum<A> for Uint512
634where
635 Self: Add<A, Output = Self>,
636{
637 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
638 iter.fold(Self::zero(), Add::add)
639 }
640}
641
642#[cfg(test)]
643mod tests {
644 use super::*;
645 use crate::math::conversion::test_try_from_int_to_uint;
646
647 #[test]
648 fn size_of_works() {
649 assert_eq!(core::mem::size_of::<Uint512>(), 64);
650 }
651
652 #[test]
653 fn uint512_new_works() {
654 let num = Uint512::new(1);
655 assert_eq!(
656 num.to_be_bytes(),
657 [
658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
659 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
660 0, 0, 0, 0, 0, 0, 0, 1
661 ]
662 );
663
664 for v in [0, 1, 18, 875786576, u128::MAX] {
665 let uut = Uint512::new(v);
667 assert_eq!(uut, Uint512::from(v));
668 }
669 }
670
671 #[test]
672 fn uint512_from_be_bytes_works() {
673 let num = Uint512::from_be_bytes([1; 64]);
674 let a: [u8; 64] = num.to_be_bytes();
675 assert_eq!(a, [1; 64]);
676
677 let be_bytes = [
678 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
679 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
680 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
681 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
682 ];
683 let num = Uint512::from_be_bytes(be_bytes);
684 let resulting_bytes: [u8; 64] = num.to_be_bytes();
685 assert_eq!(be_bytes, resulting_bytes);
686 }
687
688 #[test]
689 fn uint512_not_works() {
690 let num = Uint512::from_be_bytes([1; 64]);
691 let a = (!num).to_be_bytes();
692 assert_eq!(a, [254; 64]);
693
694 assert_eq!(!Uint512::MAX, Uint512::MIN);
695 assert_eq!(!Uint512::MIN, Uint512::MAX);
696 }
697
698 #[test]
699 fn uint512_zero_works() {
700 let zero = Uint512::zero();
701 assert_eq!(
702 zero.to_be_bytes(),
703 [
704 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
705 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
706 0, 0, 0, 0, 0, 0, 0, 0
707 ]
708 );
709 }
710
711 #[test]
712 fn uin512_one_works() {
713 let one = Uint512::one();
714 assert_eq!(
715 one.to_be_bytes(),
716 [
717 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
718 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
719 0, 0, 0, 0, 0, 0, 0, 1
720 ]
721 );
722 }
723
724 #[test]
725 fn uint512_endianness() {
726 let be_bytes = [
727 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
728 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
729 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
730 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
731 ];
732 let le_bytes = [
733 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
734 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
735 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
736 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
737 ];
738
739 let a = Uint512::from_be_bytes(be_bytes);
741 let b = Uint512::from_le_bytes(le_bytes);
742 assert_eq!(a, Uint512::from(65536u32 + 512 + 3));
743 assert_eq!(a, b);
744 }
745
746 #[test]
747 fn uint512_convert_from() {
748 let a = Uint512::from(5u128);
749 assert_eq!(a.0, U512::from(5u32));
750
751 let a = Uint512::from(5u64);
752 assert_eq!(a.0, U512::from(5u32));
753
754 let a = Uint512::from(5u32);
755 assert_eq!(a.0, U512::from(5u32));
756
757 let a = Uint512::from(5u16);
758 assert_eq!(a.0, U512::from(5u32));
759
760 let a = Uint512::from(5u8);
761 assert_eq!(a.0, U512::from(5u32));
762
763 let result = Uint512::try_from("34567");
764 assert_eq!(
765 result.unwrap().0,
766 U512::from_str_radix("34567", 10).unwrap()
767 );
768
769 let result = Uint512::try_from("1.23");
770 assert!(result.is_err());
771 }
772
773 #[test]
774 fn uint512_try_from_signed_works() {
775 test_try_from_int_to_uint::<Int64, Uint512>("Int64", "Uint512");
776 test_try_from_int_to_uint::<Int128, Uint512>("Int128", "Uint512");
777 test_try_from_int_to_uint::<Int256, Uint512>("Int256", "Uint512");
778 test_try_from_int_to_uint::<Int512, Uint512>("Int512", "Uint512");
779 }
780
781 #[test]
782 fn uint512_try_into() {
783 assert!(Uint64::try_from(Uint512::MAX).is_err());
784 assert!(Uint128::try_from(Uint512::MAX).is_err());
785 assert!(Uint256::try_from(Uint512::MAX).is_err());
786
787 assert_eq!(Uint64::try_from(Uint512::zero()), Ok(Uint64::zero()));
788 assert_eq!(Uint128::try_from(Uint512::zero()), Ok(Uint128::zero()));
789 assert_eq!(Uint256::try_from(Uint512::zero()), Ok(Uint256::zero()));
790
791 assert_eq!(
792 Uint64::try_from(Uint512::from(42u64)),
793 Ok(Uint64::from(42u64))
794 );
795 assert_eq!(
796 Uint128::try_from(Uint512::from(42u128)),
797 Ok(Uint128::from(42u128))
798 );
799 assert_eq!(
800 Uint256::try_from(Uint512::from(42u128)),
801 Ok(Uint256::from(42u128))
802 );
803 }
804
805 #[test]
806 fn uint512_convert_to_uint128() {
807 let source = Uint512::from(42u128);
808 let target = Uint128::try_from(source);
809 assert_eq!(target, Ok(Uint128::new(42u128)));
810
811 let source = Uint512::MAX;
812 let target = Uint128::try_from(source);
813 assert_eq!(
814 target,
815 Err(ConversionOverflowError::new("Uint512", "Uint128"))
816 );
817 }
818
819 #[test]
820 fn uint512_from_uint256() {
821 assert_eq!(
822 Uint512::from_uint256(Uint256::from_str("123").unwrap()),
823 Uint512::from_str("123").unwrap()
824 );
825
826 assert_eq!(
827 Uint512::from_uint256(Uint256::from_str("9785746283745").unwrap()),
828 Uint512::from_str("9785746283745").unwrap()
829 );
830
831 assert_eq!(
832 Uint512::from_uint256(
833 Uint256::from_str(
834 "97857462837575757832978493758398593853985452378423874623874628736482736487236"
835 )
836 .unwrap()
837 ),
838 Uint512::from_str(
839 "97857462837575757832978493758398593853985452378423874623874628736482736487236"
840 )
841 .unwrap()
842 );
843 }
844
845 #[test]
846 fn uint512_implements_display() {
847 let a = Uint512::from(12345u32);
848 assert_eq!(format!("Embedded: {a}"), "Embedded: 12345");
849 assert_eq!(a.to_string(), "12345");
850
851 let a = Uint512::zero();
852 assert_eq!(format!("Embedded: {a}"), "Embedded: 0");
853 assert_eq!(a.to_string(), "0");
854 }
855
856 #[test]
857 fn uint512_display_padding_works() {
858 let a = Uint512::from(123u64);
860 assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
861
862 let a = Uint512::from(123u64);
864 assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123");
865 }
866
867 #[test]
868 fn uint512_to_be_bytes_works() {
869 assert_eq!(
870 Uint512::zero().to_be_bytes(),
871 [
872 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
873 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
874 0, 0, 0, 0, 0, 0, 0, 0,
875 ]
876 );
877 assert_eq!(
878 Uint512::MAX.to_be_bytes(),
879 [
880 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
881 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
882 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
883 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
884 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
885 ]
886 );
887 assert_eq!(
888 Uint512::from(1u128).to_be_bytes(),
889 [
890 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
891 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
892 0, 0, 0, 0, 0, 0, 0, 1
893 ]
894 );
895 assert_eq!(
897 Uint512::from(240282366920938463463374607431768124608u128).to_be_bytes(),
898 [
899 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
900 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 179, 87, 165,
901 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192
902 ]
903 );
904 assert_eq!(
905 Uint512::from_be_bytes([
906 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
907 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
908 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
909 252, 96, 230, 187, 38, 29
910 ])
911 .to_be_bytes(),
912 [
913 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
914 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
915 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
916 252, 96, 230, 187, 38, 29
917 ]
918 );
919 }
920
921 #[test]
922 fn uint512_to_le_bytes_works() {
923 assert_eq!(
924 Uint512::zero().to_le_bytes(),
925 [
926 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
927 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
928 0, 0, 0, 0, 0, 0, 0, 0
929 ]
930 );
931 assert_eq!(
932 Uint512::MAX.to_le_bytes(),
933 [
934 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
935 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
936 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
937 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
938 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
939 ]
940 );
941 assert_eq!(
942 Uint512::from(1u128).to_le_bytes(),
943 [
944 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
945 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
946 0, 0, 0, 0, 0, 0, 0, 0
947 ]
948 );
949 assert_eq!(
951 Uint512::from(240282366920938463463374607431768124608u128).to_le_bytes(),
952 [
953 192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 0, 0,
954 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
955 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
956 ]
957 );
958 assert_eq!(
959 Uint512::from_be_bytes([
960 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
961 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
962 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
963 252, 96, 230, 187, 38, 29
964 ])
965 .to_le_bytes(),
966 [
967 29, 38, 187, 230, 96, 252, 8, 99, 12, 47, 22, 13, 59, 44, 10, 64, 73, 154, 195,
968 166, 88, 14, 22, 85, 119, 238, 134, 208, 45, 106, 88, 218, 240, 150, 115, 200, 240,
969 2, 233, 42, 7, 192, 201, 211, 54, 65, 76, 87, 78, 67, 21, 33, 38, 0, 91, 58, 200,
970 123, 67, 87, 32, 23, 4, 17
971 ]
972 );
973 }
974
975 #[test]
976 fn uint512_is_zero_works() {
977 assert!(Uint512::zero().is_zero());
978 assert!(Uint512(U512::from(0u32)).is_zero());
979
980 assert!(!Uint512::from(1u32).is_zero());
981 assert!(!Uint512::from(123u32).is_zero());
982 }
983
984 #[test]
985 fn uint512_wrapping_methods() {
986 assert_eq!(
988 Uint512::from(2u32).wrapping_add(Uint512::from(2u32)),
989 Uint512::from(4u32)
990 ); assert_eq!(
992 Uint512::MAX.wrapping_add(Uint512::from(1u32)),
993 Uint512::from(0u32)
994 ); assert_eq!(
998 Uint512::from(7u32).wrapping_sub(Uint512::from(5u32)),
999 Uint512::from(2u32)
1000 ); assert_eq!(
1002 Uint512::from(0u32).wrapping_sub(Uint512::from(1u32)),
1003 Uint512::MAX
1004 ); assert_eq!(
1008 Uint512::from(3u32).wrapping_mul(Uint512::from(2u32)),
1009 Uint512::from(6u32)
1010 ); assert_eq!(
1012 Uint512::MAX.wrapping_mul(Uint512::from(2u32)),
1013 Uint512::MAX - Uint512::one()
1014 ); assert_eq!(Uint512::from(2u32).wrapping_pow(3), Uint512::from(8u32)); assert_eq!(Uint512::MAX.wrapping_pow(2), Uint512::from(1u32)); }
1020
1021 #[test]
1022 fn uint512_json() {
1023 let orig = Uint512::from(1234567890987654321u128);
1024 let serialized = serde_json::to_vec(&orig).unwrap();
1025 assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
1026 let parsed: Uint512 = serde_json::from_slice(&serialized).unwrap();
1027 assert_eq!(parsed, orig);
1028 }
1029
1030 #[test]
1031 fn uint512_compare() {
1032 let a = Uint512::from(12345u32);
1033 let b = Uint512::from(23456u32);
1034
1035 assert!(a < b);
1036 assert!(b > a);
1037 assert_eq!(a, Uint512::from(12345u32));
1038 }
1039
1040 #[test]
1041 #[allow(clippy::op_ref)]
1042 fn uint512_math() {
1043 let a = Uint512::from(12345u32);
1044 let b = Uint512::from(23456u32);
1045
1046 let mut c = Uint512::from(300000u32);
1048 c += b;
1049 assert_eq!(c, Uint512::from(323456u32));
1050 let mut d = Uint512::from(300000u32);
1051 d += &b;
1052 assert_eq!(d, Uint512::from(323456u32));
1053
1054 let mut c = Uint512::from(300000u32);
1056 c -= b;
1057 assert_eq!(c, Uint512::from(276544u32));
1058 let mut d = Uint512::from(300000u32);
1059 d -= &b;
1060 assert_eq!(d, Uint512::from(276544u32));
1061
1062 let underflow_result = a.checked_sub(b);
1064 let OverflowError { operation } = underflow_result.unwrap_err();
1065 assert_eq!(operation, OverflowOperation::Sub);
1066 }
1067
1068 #[test]
1069 #[allow(clippy::op_ref)]
1070 fn uint512_add_works() {
1071 assert_eq!(
1072 Uint512::from(2u32) + Uint512::from(1u32),
1073 Uint512::from(3u32)
1074 );
1075 assert_eq!(
1076 Uint512::from(2u32) + Uint512::from(0u32),
1077 Uint512::from(2u32)
1078 );
1079
1080 let a = Uint512::from(10u32);
1082 let b = Uint512::from(3u32);
1083 let expected = Uint512::from(13u32);
1084 assert_eq!(a + b, expected);
1085 assert_eq!(a + &b, expected);
1086 assert_eq!(&a + b, expected);
1087 assert_eq!(&a + &b, expected);
1088 }
1089
1090 #[test]
1091 #[should_panic(expected = "attempt to add with overflow")]
1092 fn uint512_add_overflow_panics() {
1093 let max = Uint512::MAX;
1094 let _ = max + Uint512::from(12u32);
1095 }
1096
1097 #[test]
1098 #[allow(clippy::op_ref)]
1099 fn uint512_sub_works() {
1100 assert_eq!(
1101 Uint512::from(2u32) - Uint512::from(1u32),
1102 Uint512::from(1u32)
1103 );
1104 assert_eq!(
1105 Uint512::from(2u32) - Uint512::from(0u32),
1106 Uint512::from(2u32)
1107 );
1108 assert_eq!(
1109 Uint512::from(2u32) - Uint512::from(2u32),
1110 Uint512::from(0u32)
1111 );
1112
1113 let a = Uint512::from(10u32);
1115 let b = Uint512::from(3u32);
1116 let expected = Uint512::from(7u32);
1117 assert_eq!(a - b, expected);
1118 assert_eq!(a - &b, expected);
1119 assert_eq!(&a - b, expected);
1120 assert_eq!(&a - &b, expected);
1121 }
1122
1123 #[test]
1124 #[should_panic]
1125 fn uint512_sub_overflow_panics() {
1126 let _ = Uint512::from(1u32) - Uint512::from(2u32);
1127 }
1128
1129 #[test]
1130 fn uint512_sub_assign_works() {
1131 let mut a = Uint512::from(14u32);
1132 a -= Uint512::from(2u32);
1133 assert_eq!(a, Uint512::from(12u32));
1134
1135 let mut a = Uint512::from(10u32);
1137 let b = Uint512::from(3u32);
1138 let expected = Uint512::from(7u32);
1139 a -= &b;
1140 assert_eq!(a, expected);
1141 }
1142
1143 #[test]
1144 #[allow(clippy::op_ref)]
1145 fn uint512_mul_works() {
1146 assert_eq!(
1147 Uint512::from(2u32) * Uint512::from(3u32),
1148 Uint512::from(6u32)
1149 );
1150 assert_eq!(Uint512::from(2u32) * Uint512::zero(), Uint512::zero());
1151
1152 let a = Uint512::from(11u32);
1154 let b = Uint512::from(3u32);
1155 let expected = Uint512::from(33u32);
1156 assert_eq!(a * b, expected);
1157 assert_eq!(a * &b, expected);
1158 assert_eq!(&a * b, expected);
1159 assert_eq!(&a * &b, expected);
1160 }
1161
1162 #[test]
1163 fn uint512_mul_assign_works() {
1164 let mut a = Uint512::from(14u32);
1165 a *= Uint512::from(2u32);
1166 assert_eq!(a, Uint512::from(28u32));
1167
1168 let mut a = Uint512::from(10u32);
1170 let b = Uint512::from(3u32);
1171 a *= &b;
1172 assert_eq!(a, Uint512::from(30u32));
1173 }
1174
1175 #[test]
1176 fn uint512_pow_works() {
1177 assert_eq!(Uint512::from(2u32).pow(2), Uint512::from(4u32));
1178 assert_eq!(Uint512::from(2u32).pow(10), Uint512::from(1024u32));
1179 }
1180
1181 #[test]
1182 #[should_panic]
1183 fn uint512_pow_overflow_panics() {
1184 _ = Uint512::MAX.pow(2u32);
1185 }
1186
1187 #[test]
1188 fn uint512_shr_works() {
1189 let original = Uint512::from_be_bytes([
1190 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1191 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1192 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1193 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1194 ]);
1195
1196 let shifted = Uint512::from_be_bytes([
1197 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1198 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1199 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1200 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1201 ]);
1202
1203 assert_eq!(original >> 2u32, shifted);
1204 }
1205
1206 #[test]
1207 #[should_panic]
1208 fn uint512_shr_overflow_panics() {
1209 let _ = Uint512::from(1u32) >> 512u32;
1210 }
1211
1212 #[test]
1213 fn uint512_shl_works() {
1214 let original = Uint512::from_be_bytes([
1215 64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1216 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1217 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1218 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1219 ]);
1220
1221 let shifted = Uint512::from_be_bytes([
1222 2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1223 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1224 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1225 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1226 ]);
1227
1228 assert_eq!(original << 2u32, shifted);
1229 }
1230
1231 #[test]
1232 #[should_panic]
1233 fn uint512_shl_overflow_panics() {
1234 let _ = Uint512::from(1u32) << 512u32;
1235 }
1236
1237 #[test]
1238 fn sum_works() {
1239 let nums = vec![
1240 Uint512::from(17u32),
1241 Uint512::from(123u32),
1242 Uint512::from(540u32),
1243 Uint512::from(82u32),
1244 ];
1245 let expected = Uint512::from(762u32);
1246
1247 let sum_as_ref: Uint512 = nums.iter().sum();
1248 assert_eq!(expected, sum_as_ref);
1249
1250 let sum_as_owned: Uint512 = nums.into_iter().sum();
1251 assert_eq!(expected, sum_as_owned);
1252 }
1253
1254 #[test]
1255 fn uint512_methods() {
1256 assert!(matches!(
1258 Uint512::MAX.checked_add(Uint512::from(1u32)),
1259 Err(OverflowError { .. })
1260 ));
1261 assert_eq!(
1262 Uint512::from(1u32).checked_add(Uint512::from(1u32)),
1263 Ok(Uint512::from(2u32)),
1264 );
1265 assert!(matches!(
1266 Uint512::from(0u32).checked_sub(Uint512::from(1u32)),
1267 Err(OverflowError { .. })
1268 ));
1269 assert_eq!(
1270 Uint512::from(2u32).checked_sub(Uint512::from(1u32)),
1271 Ok(Uint512::from(1u32)),
1272 );
1273 assert!(matches!(
1274 Uint512::MAX.checked_mul(Uint512::from(2u32)),
1275 Err(OverflowError { .. })
1276 ));
1277 assert_eq!(
1278 Uint512::from(2u32).checked_mul(Uint512::from(2u32)),
1279 Ok(Uint512::from(4u32)),
1280 );
1281 assert!(matches!(
1282 Uint512::MAX.checked_pow(2u32),
1283 Err(OverflowError { .. })
1284 ));
1285 assert_eq!(
1286 Uint512::from(2u32).checked_pow(3u32),
1287 Ok(Uint512::from(8u32)),
1288 );
1289 assert!(matches!(
1290 Uint512::MAX.checked_div(Uint512::from(0u32)),
1291 Err(DivideByZeroError { .. })
1292 ));
1293 assert_eq!(
1294 Uint512::from(6u32).checked_div(Uint512::from(2u32)),
1295 Ok(Uint512::from(3u32)),
1296 );
1297 assert!(matches!(
1298 Uint512::MAX.checked_div_euclid(Uint512::from(0u32)),
1299 Err(DivideByZeroError { .. })
1300 ));
1301 assert_eq!(
1302 Uint512::from(6u32).checked_div_euclid(Uint512::from(2u32)),
1303 Ok(Uint512::from(3u32)),
1304 );
1305 assert_eq!(
1306 Uint512::from(7u32).checked_div_euclid(Uint512::from(2u32)),
1307 Ok(Uint512::from(3u32)),
1308 );
1309 assert!(matches!(
1310 Uint512::MAX.checked_rem(Uint512::from(0u32)),
1311 Err(DivideByZeroError { .. })
1312 ));
1313
1314 assert_eq!(
1316 Uint512::MAX.saturating_add(Uint512::from(1u32)),
1317 Uint512::MAX
1318 );
1319 assert_eq!(
1320 Uint512::from(0u32).saturating_sub(Uint512::from(1u32)),
1321 Uint512::from(0u32)
1322 );
1323 assert_eq!(
1324 Uint512::MAX.saturating_mul(Uint512::from(2u32)),
1325 Uint512::MAX
1326 );
1327 assert_eq!(
1328 Uint512::from(4u32).saturating_pow(2u32),
1329 Uint512::from(16u32)
1330 );
1331 assert_eq!(Uint512::MAX.saturating_pow(2u32), Uint512::MAX);
1332 }
1333
1334 #[test]
1335 #[allow(clippy::op_ref)]
1336 fn uint512_implements_rem() {
1337 let a = Uint512::from(10u32);
1338 assert_eq!(a % Uint512::from(10u32), Uint512::zero());
1339 assert_eq!(a % Uint512::from(2u32), Uint512::zero());
1340 assert_eq!(a % Uint512::from(1u32), Uint512::zero());
1341 assert_eq!(a % Uint512::from(3u32), Uint512::from(1u32));
1342 assert_eq!(a % Uint512::from(4u32), Uint512::from(2u32));
1343
1344 let a = Uint512::from(10u32);
1346 let b = Uint512::from(3u32);
1347 let expected = Uint512::from(1u32);
1348 assert_eq!(a % b, expected);
1349 assert_eq!(a % &b, expected);
1350 assert_eq!(&a % b, expected);
1351 assert_eq!(&a % &b, expected);
1352 }
1353
1354 #[test]
1355 #[should_panic(expected = "divisor of zero")]
1356 fn uint512_rem_panics_for_zero() {
1357 let _ = Uint512::from(10u32) % Uint512::zero();
1358 }
1359
1360 #[test]
1361 #[allow(clippy::op_ref)]
1362 fn uint512_rem_works() {
1363 assert_eq!(
1364 Uint512::from(12u32) % Uint512::from(10u32),
1365 Uint512::from(2u32)
1366 );
1367 assert_eq!(Uint512::from(50u32) % Uint512::from(5u32), Uint512::zero());
1368
1369 let a = Uint512::from(42u32);
1371 let b = Uint512::from(5u32);
1372 let expected = Uint512::from(2u32);
1373 assert_eq!(a % b, expected);
1374 assert_eq!(a % &b, expected);
1375 assert_eq!(&a % b, expected);
1376 assert_eq!(&a % &b, expected);
1377 }
1378
1379 #[test]
1380 fn uint512_rem_assign_works() {
1381 let mut a = Uint512::from(30u32);
1382 a %= Uint512::from(4u32);
1383 assert_eq!(a, Uint512::from(2u32));
1384
1385 let mut a = Uint512::from(25u32);
1387 let b = Uint512::from(6u32);
1388 a %= &b;
1389 assert_eq!(a, Uint512::from(1u32));
1390 }
1391
1392 #[test]
1393 fn uint512_strict_add_works() {
1394 let a = Uint512::from(5u32);
1395 let b = Uint512::from(3u32);
1396 assert_eq!(a.strict_add(b), Uint512::from(8u32));
1397 assert_eq!(b.strict_add(a), Uint512::from(8u32));
1398 }
1399
1400 #[test]
1401 #[should_panic(expected = "attempt to add with overflow")]
1402 fn uint512_strict_add_panics_on_overflow() {
1403 let a = Uint512::MAX;
1404 let b = Uint512::ONE;
1405 let _ = a.strict_add(b);
1406 }
1407
1408 #[test]
1409 fn uint512_strict_sub_works() {
1410 let a = Uint512::from(5u32);
1411 let b = Uint512::from(3u32);
1412 assert_eq!(a.strict_sub(b), Uint512::from(2u32));
1413 }
1414
1415 #[test]
1416 #[should_panic(expected = "attempt to subtract with overflow")]
1417 fn uint512_strict_sub_panics_on_overflow() {
1418 let a = Uint512::ZERO;
1419 let b = Uint512::ONE;
1420 let _ = a.strict_sub(b);
1421 }
1422
1423 #[test]
1424 fn uint512_abs_diff_works() {
1425 let a = Uint512::from(42u32);
1426 let b = Uint512::from(5u32);
1427 let expected = Uint512::from(37u32);
1428 assert_eq!(a.abs_diff(b), expected);
1429 assert_eq!(b.abs_diff(a), expected);
1430 }
1431
1432 #[test]
1433 fn uint512_partial_eq() {
1434 let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1435 .into_iter()
1436 .map(|(lhs, rhs, expected): (u64, u64, bool)| {
1437 (Uint512::from(lhs), Uint512::from(rhs), expected)
1438 });
1439
1440 #[allow(clippy::op_ref)]
1441 for (lhs, rhs, expected) in test_cases {
1442 assert_eq!(lhs == rhs, expected);
1443 assert_eq!(&lhs == rhs, expected);
1444 assert_eq!(lhs == &rhs, expected);
1445 assert_eq!(&lhs == &rhs, expected);
1446 }
1447 }
1448}