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