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