@@ -26,13 +26,14 @@ use super::num_consts::NumConsts;
26
26
///
27
27
/// # Examples
28
28
///
29
- /// Use `from ` to create instances out of primitive uint types or `new` to provide big
30
- /// endian bytes:
29
+ /// Use `new ` to create instances out of i128, `from` for other primitive uint/int types
30
+ /// or `from_be_bytes` to provide big endian bytes:
31
31
///
32
32
/// ```
33
33
/// # use cosmwasm_std::Int512;
34
- /// let a = Int512::from(258u128);
35
- /// let b = Int512::new([
34
+ /// let a = Int512::new(258i128);
35
+ /// let b = Int512::from(258u128);
36
+ /// let c = Int512::from_be_bytes([
36
37
/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
37
38
/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
38
39
/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
@@ -43,6 +44,7 @@ use super::num_consts::NumConsts;
43
44
/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8,
44
45
/// ]);
45
46
/// assert_eq!(a, b);
47
+ /// assert_eq!(a, c);
46
48
/// ```
47
49
#[ derive( Copy , Clone , Default , Debug , PartialEq , Eq , PartialOrd , Ord , schemars:: JsonSchema ) ]
48
50
pub struct Int512 ( #[ schemars( with = "String" ) ] pub ( crate ) I512 ) ;
@@ -54,11 +56,33 @@ impl Int512 {
54
56
pub const MAX : Int512 = Int512 ( I512 :: MAX ) ;
55
57
pub const MIN : Int512 = Int512 ( I512 :: MIN ) ;
56
58
57
- /// Creates a Int512(value) from a big endian representation. It's just an alias for
58
- /// `from_be_bytes`.
59
+ /// Creates a Int512(value).
60
+ ///
61
+ /// This method is less flexible than `from` but can be called in a const context.
62
+ ///
63
+ /// Before CosmWasm 3 this took a byte array as an argument. You can get this behaviour
64
+ /// with [`from_be_bytes`].
65
+ ///
66
+ /// [`from_be_bytes`]: Self::from_be_bytes
59
67
#[ inline]
60
- pub const fn new ( value : [ u8 ; 64 ] ) -> Self {
61
- Self :: from_be_bytes ( value)
68
+ pub const fn new ( value : i128 ) -> Self {
69
+ // See https://en.wikipedia.org/wiki/Sign_extension
70
+ let b = value. to_be_bytes ( ) ;
71
+ if value. is_negative ( ) {
72
+ Self :: from_be_bytes ( [
73
+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
74
+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
75
+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
76
+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , b[ 0 ] , b[ 1 ] , b[ 2 ] , b[ 3 ] , b[ 4 ] , b[ 5 ] , b[ 6 ] , b[ 7 ] ,
77
+ b[ 8 ] , b[ 9 ] , b[ 10 ] , b[ 11 ] , b[ 12 ] , b[ 13 ] , b[ 14 ] , b[ 15 ] ,
78
+ ] )
79
+ } else {
80
+ Self :: from_be_bytes ( [
81
+ 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 ,
82
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , b[ 0 ] , b[ 1 ] , b[ 2 ] , b[ 3 ] ,
83
+ b[ 4 ] , b[ 5 ] , b[ 6 ] , b[ 7 ] , b[ 8 ] , b[ 9 ] , b[ 10 ] , b[ 11 ] , b[ 12 ] , b[ 13 ] , b[ 14 ] , b[ 15 ] ,
84
+ ] )
85
+ }
62
86
}
63
87
64
88
/// Creates a Int512(0)
@@ -585,7 +609,37 @@ mod tests {
585
609
586
610
#[ test]
587
611
fn int512_new_works ( ) {
588
- let num = Int512 :: new ( [ 1 ; 64 ] ) ;
612
+ let num = Int512 :: new ( 1 ) ;
613
+ assert_eq ! (
614
+ num. to_be_bytes( ) ,
615
+ [
616
+ 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 ,
617
+ 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 ,
618
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1
619
+ ]
620
+ ) ;
621
+
622
+ let num = Int512 :: new ( -1 ) ;
623
+ assert_eq ! (
624
+ num. to_be_bytes( ) ,
625
+ [
626
+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
627
+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
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
+ ]
631
+ ) ;
632
+
633
+ for v in [ 0 , 1 , -4 , 18 , 875786576 , -11763498739 , i128:: MAX , i128:: MIN ] {
634
+ // From is implemented by bnum, so we test two independent implementations against each other
635
+ let uut = Int512 :: new ( v) ;
636
+ assert_eq ! ( uut, Int512 :: from( v) ) ;
637
+ }
638
+ }
639
+
640
+ #[ test]
641
+ fn int512_from_be_bytes_works ( ) {
642
+ let num = Int512 :: from_be_bytes ( [ 1 ; 64 ] ) ;
589
643
let a: [ u8 ; 64 ] = num. to_be_bytes ( ) ;
590
644
assert_eq ! ( a, [ 1 ; 64 ] ) ;
591
645
@@ -595,14 +649,14 @@ mod tests {
595
649
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 ,
596
650
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 1u8 , 2u8 , 3u8 ,
597
651
] ;
598
- let num = Int512 :: new ( be_bytes) ;
652
+ let num = Int512 :: from_be_bytes ( be_bytes) ;
599
653
let resulting_bytes: [ u8 ; 64 ] = num. to_be_bytes ( ) ;
600
654
assert_eq ! ( be_bytes, resulting_bytes) ;
601
655
}
602
656
603
657
#[ test]
604
658
fn int512_not_works ( ) {
605
- let num = Int512 :: new ( [ 1 ; 64 ] ) ;
659
+ let num = Int512 :: from_be_bytes ( [ 1 ; 64 ] ) ;
606
660
let a = ( !num) . to_be_bytes ( ) ;
607
661
assert_eq ! ( a, [ 254 ; 64 ] ) ;
608
662
@@ -643,12 +697,10 @@ mod tests {
643
697
] ;
644
698
645
699
// These should all be the same.
646
- let num1 = Int512 :: new ( be_bytes) ;
647
- let num2 = Int512 :: from_be_bytes ( be_bytes) ;
648
- let num3 = Int512 :: from_le_bytes ( le_bytes) ;
649
- assert_eq ! ( num1, Int512 :: from( 65536u32 + 512 + 3 ) ) ;
650
- assert_eq ! ( num1, num2) ;
651
- assert_eq ! ( num1, num3) ;
700
+ let a = Int512 :: from_be_bytes ( be_bytes) ;
701
+ let b = Int512 :: from_le_bytes ( le_bytes) ;
702
+ assert_eq ! ( a, Int512 :: from( 65536u32 + 512 + 3 ) ) ;
703
+ assert_eq ! ( a, b) ;
652
704
}
653
705
654
706
#[ test]
@@ -1028,14 +1080,14 @@ mod tests {
1028
1080
1029
1081
#[ test]
1030
1082
fn int512_shr_works ( ) {
1031
- let original = Int512 :: new ( [
1083
+ let original = Int512 :: from_be_bytes ( [
1032
1084
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 ,
1033
1085
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 ,
1034
1086
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 ,
1035
1087
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 2u8 , 0u8 , 4u8 , 2u8 ,
1036
1088
] ) ;
1037
1089
1038
- let shifted = Int512 :: new ( [
1090
+ let shifted = Int512 :: from_be_bytes ( [
1039
1091
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 ,
1040
1092
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 ,
1041
1093
0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 ,
0 commit comments