@@ -11,10 +11,10 @@ const U128_LO_MASK: u128 = u64::MAX as u128;
11
11
12
12
/// A 256-bit unsigned integer represented as two 128-bit native-endian limbs.
13
13
#[ allow( non_camel_case_types) ]
14
- #[ derive( Clone , Copy , Debug , PartialEq , PartialOrd ) ]
14
+ #[ derive( Clone , Copy , Debug , PartialEq , PartialOrd , Eq , Ord ) ]
15
15
pub struct u256 {
16
- pub lo : u128 ,
17
16
pub hi : u128 ,
17
+ pub lo : u128 ,
18
18
}
19
19
20
20
impl u256 {
@@ -28,17 +28,17 @@ impl u256 {
28
28
pub fn signed ( self ) -> i256 {
29
29
i256 {
30
30
lo : self . lo ,
31
- hi : self . hi ,
31
+ hi : self . hi as i128 ,
32
32
}
33
33
}
34
34
}
35
35
36
36
/// A 256-bit signed integer represented as two 128-bit native-endian limbs.
37
37
#[ allow( non_camel_case_types) ]
38
- #[ derive( Clone , Copy , Debug , PartialEq , PartialOrd ) ]
38
+ #[ derive( Clone , Copy , Debug , PartialEq , PartialOrd , Eq , Ord ) ]
39
39
pub struct i256 {
40
+ pub hi : i128 ,
40
41
pub lo : u128 ,
41
- pub hi : u128 ,
42
42
}
43
43
44
44
impl i256 {
@@ -47,7 +47,7 @@ impl i256 {
47
47
pub fn unsigned ( self ) -> u256 {
48
48
u256 {
49
49
lo : self . lo ,
50
- hi : self . hi ,
50
+ hi : self . hi as u128 ,
51
51
}
52
52
}
53
53
}
@@ -73,17 +73,17 @@ impl MinInt for i256 {
73
73
74
74
type Unsigned = u256 ;
75
75
76
- const SIGNED : bool = false ;
76
+ const SIGNED : bool = true ;
77
77
const BITS : u32 = 256 ;
78
78
const ZERO : Self = Self { lo : 0 , hi : 0 } ;
79
79
const ONE : Self = Self { lo : 1 , hi : 0 } ;
80
80
const MIN : Self = Self {
81
- lo : 0 ,
82
- hi : 1 << 127 ,
81
+ lo : u128 :: MIN ,
82
+ hi : i128 :: MIN ,
83
83
} ;
84
84
const MAX : Self = Self {
85
85
lo : u128:: MAX ,
86
- hi : u128 :: MAX >> 1 ,
86
+ hi : i128 :: MAX ,
87
87
} ;
88
88
}
89
89
@@ -109,60 +109,86 @@ macro_rules! impl_common {
109
109
}
110
110
}
111
111
112
- impl ops:: Shl < u32 > for $ty {
112
+ impl ops:: Add < Self > for $ty {
113
113
type Output = Self ;
114
114
115
- fn shl( self , _rhs: u32 ) -> Self :: Output {
116
- unimplemented!( "only used to meet trait bounds" )
115
+ fn add( self , rhs: Self ) -> Self :: Output {
116
+ let ( lo, carry) = self . lo. overflowing_add( rhs. lo) ;
117
+ let ( hi, of) = Int :: carrying_add( self . hi, rhs. hi, carry) ;
118
+ debug_assert!( !of, "attempt to add with overflow" ) ;
119
+ Self { lo, hi }
117
120
}
118
121
}
119
- } ;
120
- }
121
122
122
- impl_common ! ( i256 ) ;
123
- impl_common ! ( u256 ) ;
123
+ impl ops :: Sub < Self > for $ty {
124
+ type Output = Self ;
124
125
125
- impl ops:: Add < Self > for u256 {
126
- type Output = Self ;
126
+ fn sub( self , rhs: Self ) -> Self :: Output {
127
+ let ( lo, borrow) = self . lo. overflowing_sub( rhs. lo) ;
128
+ let ( hi, of) = Int :: borrowing_sub( self . hi, rhs. hi, borrow) ;
129
+ debug_assert!( !of, "attempt to subtract with overflow" ) ;
130
+ Self { lo, hi }
131
+ }
132
+ }
127
133
128
- fn add ( self , rhs : Self ) -> Self :: Output {
129
- let ( lo, carry) = self . lo . overflowing_add ( rhs. lo ) ;
130
- let hi = self . hi . wrapping_add ( carry as u128 ) . wrapping_add ( rhs. hi ) ;
134
+ impl ops:: Shl <u32 > for $ty {
135
+ type Output = Self ;
131
136
132
- Self { lo, hi }
133
- }
134
- }
137
+ fn shl( mut self , rhs: u32 ) -> Self :: Output {
138
+ debug_assert!( rhs < Self :: BITS , "attempt to shift left with overflow" ) ;
135
139
136
- impl ops:: Shr < u32 > for u256 {
137
- type Output = Self ;
140
+ let half_bits = Self :: BITS / 2 ;
141
+ let low_mask = half_bits - 1 ;
142
+ let s = rhs & low_mask;
138
143
139
- fn shr ( mut self , rhs : u32 ) -> Self :: Output {
140
- debug_assert ! ( rhs < Self :: BITS , "attempted to shift right with overflow" ) ;
141
- if rhs >= Self :: BITS {
142
- return Self :: ZERO ;
143
- }
144
+ let lo = self . lo;
145
+ let hi = self . hi;
144
146
145
- if rhs == 0 {
146
- return self ;
147
- }
147
+ self . lo = lo << s;
148
148
149
- if rhs < 128 {
150
- self . lo >>= rhs;
151
- self . lo |= self . hi << ( 128 - rhs) ;
152
- } else {
153
- self . lo = self . hi >> ( rhs - 128 ) ;
149
+ if rhs & half_bits == 0 {
150
+ self . hi = ( lo >> ( low_mask ^ s) >> 1 ) as _;
151
+ self . hi |= hi << s;
152
+ } else {
153
+ self . hi = self . lo as _;
154
+ self . lo = 0 ;
155
+ }
156
+ self
157
+ }
154
158
}
155
159
156
- if rhs < 128 {
157
- self . hi >>= rhs;
158
- } else {
159
- self . hi = 0 ;
160
- }
160
+ impl ops:: Shr <u32 > for $ty {
161
+ type Output = Self ;
161
162
162
- self
163
- }
163
+ fn shr( mut self , rhs: u32 ) -> Self :: Output {
164
+ debug_assert!( rhs < Self :: BITS , "attempt to shift right with overflow" ) ;
165
+
166
+ let half_bits = Self :: BITS / 2 ;
167
+ let low_mask = half_bits - 1 ;
168
+ let s = rhs & low_mask;
169
+
170
+ let lo = self . lo;
171
+ let hi = self . hi;
172
+
173
+ self . hi = hi >> s;
174
+
175
+ #[ allow( unused_comparisons) ]
176
+ if rhs & half_bits == 0 {
177
+ self . lo = ( hi << ( low_mask ^ s) << 1 ) as _;
178
+ self . lo |= lo >> s;
179
+ } else {
180
+ self . lo = self . hi as _;
181
+ self . hi = if hi < 0 { !0 } else { 0 } ;
182
+ }
183
+ self
184
+ }
185
+ }
186
+ } ;
164
187
}
165
188
189
+ impl_common ! ( i256) ;
190
+ impl_common ! ( u256) ;
191
+
166
192
impl HInt for u128 {
167
193
type D = u256 ;
168
194
@@ -200,19 +226,18 @@ impl HInt for u128 {
200
226
}
201
227
202
228
fn widen_hi ( self ) -> Self :: D {
203
- self . widen ( ) << < Self as MinInt > :: BITS
229
+ u256 { lo : 0 , hi : self }
204
230
}
205
231
}
206
232
207
233
impl HInt for i128 {
208
234
type D = i256 ;
209
235
210
236
fn widen ( self ) -> Self :: D {
211
- let mut ret = self . unsigned ( ) . zero_widen ( ) . signed ( ) ;
212
- if self . is_negative ( ) {
213
- ret . hi = u128 :: MAX ;
237
+ i256 {
238
+ lo : self as u128 ,
239
+ hi : if self < 0 { - 1 } else { 0 } ,
214
240
}
215
- ret
216
241
}
217
242
218
243
fn zero_widen ( self ) -> Self :: D {
@@ -228,7 +253,7 @@ impl HInt for i128 {
228
253
}
229
254
230
255
fn widen_hi ( self ) -> Self :: D {
231
- self . widen ( ) << < Self as MinInt > :: BITS
256
+ i256 { lo : 0 , hi : self }
232
257
}
233
258
}
234
259
@@ -252,6 +277,6 @@ impl DInt for i256 {
252
277
}
253
278
254
279
fn hi ( self ) -> Self :: H {
255
- self . hi as i128
280
+ self . hi
256
281
}
257
282
}
0 commit comments