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