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