@@ -12,26 +12,26 @@ const WORD_FULL_MASK: u64 = 0xffffffffffffffff;
1212// Stored little endian
1313#[ allow( non_camel_case_types) ]
1414#[ derive( Clone , Copy , Debug , PartialEq , PartialOrd ) ]
15- pub struct u256 ( [ u64 ; 4 ] ) ;
15+ pub struct u256 ( pub [ u64 ; 4 ] ) ;
1616
1717impl u256 {
1818 /// Reinterpret as a signed integer
19- fn as_signed ( self ) -> i256 {
19+ pub fn signed ( self ) -> i256 {
2020 i256 ( self . 0 )
2121 }
2222}
2323
24- impl u256 {
24+ impl i256 {
2525 /// Reinterpret as an unsigned integer
26- fn as_unsigned ( self ) -> u256 {
26+ pub fn unsigned ( self ) -> u256 {
2727 u256 ( self . 0 )
2828 }
2929}
3030
3131// Stored little endian
3232#[ allow( non_camel_case_types) ]
3333#[ derive( Clone , Copy , Debug , PartialEq , PartialOrd ) ]
34- pub struct i256 ( [ u64 ; 4 ] ) ;
34+ pub struct i256 ( pub [ u64 ; 4 ] ) ;
3535
3636impl MinInt for u256 {
3737 type OtherSign = i256 ;
@@ -194,7 +194,6 @@ macro_rules! impl_common {
194194impl_common ! ( i256) ;
195195impl_common ! ( u256) ;
196196
197-
198197macro_rules! word {
199198 ( 1 , $val: expr) => {
200199 ( ( $val >> ( 32 * 3 ) ) & Self :: from( WORD_LO_MASK ) ) as u64
@@ -280,34 +279,36 @@ impl HInt for i128 {
280279 type D = i256 ;
281280
282281 fn widen ( self ) -> Self :: D {
283- let w0 = self & i128:: from ( u64:: MAX ) ;
284- let w1 = ( self >> u64:: BITS ) & i128:: from ( u64:: MAX ) ;
285- i256 ( [ w0 as u64 , w1 as u64 , u64:: MAX , u64:: MAX ] )
282+ let mut ret = self . unsigned ( ) . zero_widen ( ) . signed ( ) ;
283+ if self . is_negative ( ) {
284+ ret. 0 [ 2 ] = u64:: MAX ;
285+ ret. 0 [ 3 ] = u64:: MAX ;
286+ }
287+ ret
286288 }
287289
288290 fn zero_widen ( self ) -> Self :: D {
289- self . unsigned ( ) . zero_widen ( ) . as_signed ( )
291+ self . unsigned ( ) . zero_widen ( ) . signed ( )
290292 }
291293
292294 fn zero_widen_mul ( self , rhs : Self ) -> Self :: D {
293- self . unsigned ( ) . zero_widen_mul ( rhs. unsigned ( ) ) . as_signed ( )
295+ self . unsigned ( ) . zero_widen_mul ( rhs. unsigned ( ) ) . signed ( )
294296 }
295297
296298 fn widen_mul ( self , rhs : Self ) -> Self :: D {
297- let sign0 = self & ( 0b1 << 127 ) ;
298- let sign1 = rhs & ( 0b1 << 127 ) ;
299- let signed_res = sign0 ^ sign1;
300299 let mut res = self . zero_widen_mul ( rhs) ;
300+ if self . is_negative ( ) ^ rhs. is_negative ( ) {
301+ for word in res. 0 . iter_mut ( ) . rev ( ) {
302+ let zeroes = word. leading_zeros ( ) ;
303+ let leading = u64:: MAX << ( 64 - zeroes) ;
304+ * word |= leading;
305+ if zeroes != 64 {
306+ break
307+ }
308+ }
309+ }
301310
302- // if signed_res > 0 {
303- // for word in res.0.iter_mut().rev() {
304- // for shift in (0..=63).rev() {
305- // if
306- // todo!()
307- // }
308- // }
309- // }
310- todo ! ( )
311+ res
311312 }
312313}
313314
0 commit comments