@@ -337,14 +337,13 @@ impl IntBounds<&'_ IBig> {
337337 pub fn bitwidth ( self ) -> u64 {
338338 assert ! ( !self . is_empty( ) , "{self}" ) ;
339339 let min = self . from ;
340- let max = self . to - IBig :: from ( 1 ) ;
341340 if min < & IBig :: from ( 0 ) {
342341 let min_abs: UBig = UBig :: try_from ( -min) . unwrap ( ) - 1 ;
343342
344343 let bits_for_min = min_abs. bit_len ( ) ;
345344
346- let bits_for_max = if max > IBig :: from ( 0 ) {
347- let max = UBig :: try_from ( max ) . unwrap ( ) ;
345+ let bits_for_max = if * self . to > IBig :: from ( 0 ) {
346+ let max: UBig = UBig :: try_from ( self . to ) . unwrap ( ) - 1 ;
348347
349348 max. bit_len ( )
350349 } else {
@@ -353,7 +352,7 @@ impl IntBounds<&'_ IBig> {
353352
354353 ( usize:: max ( bits_for_min, bits_for_max) + 1 ) as u64
355354 } else {
356- let max = UBig :: try_from ( max ) . unwrap ( ) ;
355+ let max: UBig = UBig :: try_from ( self . to ) . unwrap ( ) - 1 ;
357356
358357 max. bit_len ( ) as u64
359358 }
@@ -429,16 +428,41 @@ mod tests {
429428 #[ test]
430429 #[ rustfmt:: skip]
431430 fn test_bound_to_bits ( ) {
431+ for unsigned_bitwidth in 0 ..5 {
432+ let to = IBig :: from ( 2_i64 . pow ( unsigned_bitwidth) ) ;
433+ assert_eq ! ( IntBounds { from: & IBig :: from( 0 ) , to: & to} . bitwidth( ) , unsigned_bitwidth as u64 ) ;
434+ assert_eq ! ( IntBounds { from: & IBig :: from( 0 ) , to: & ( & to+1 ) } . bitwidth( ) , ( unsigned_bitwidth+1 ) as u64 ) ;
435+ }
436+ for signed_bitwidth in 1 ..5 {
437+ let from = -IBig :: from ( 2_i64 . pow ( signed_bitwidth - 1 ) ) ;
438+ let to = IBig :: from ( 2_i64 . pow ( signed_bitwidth - 1 ) ) ;
439+ assert_eq ! ( IntBounds { from: & from, to: & to} . bitwidth( ) , signed_bitwidth as u64 ) ;
440+ assert_eq ! ( IntBounds { from: & ( & from-1 ) , to: & to} . bitwidth( ) , ( signed_bitwidth+1 ) as u64 ) ;
441+ assert_eq ! ( IntBounds { from: & from, to: & ( & to+1 ) } . bitwidth( ) , ( signed_bitwidth+1 ) as u64 ) ;
442+ }
443+ // Try one-sided negative numbers
444+ assert_eq ! ( IntBounds { from: & IBig :: from( -1 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 1 ) ;
445+ assert_eq ! ( IntBounds { from: & IBig :: from( -2 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 2 ) ;
446+ assert_eq ! ( IntBounds { from: & IBig :: from( -3 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 3 ) ;
447+ assert_eq ! ( IntBounds { from: & IBig :: from( -4 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 3 ) ;
448+ assert_eq ! ( IntBounds { from: & IBig :: from( -5 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 4 ) ;
449+ assert_eq ! ( IntBounds { from: & IBig :: from( -6 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 4 ) ;
450+ assert_eq ! ( IntBounds { from: & IBig :: from( -7 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 4 ) ;
451+ assert_eq ! ( IntBounds { from: & IBig :: from( -8 ) , to: & IBig :: from( 0 ) } . bitwidth( ) , 4 ) ;
452+
453+ assert_eq ! ( IntBounds { from: & IBig :: from( 0 ) , to: & IBig :: from( 1 ) } . bitwidth( ) , 0 ) ; // Zero sized wires are now possible
454+ assert_eq ! ( IntBounds { from: & IBig :: from( 0 ) , to: & IBig :: from( 256 ) } . bitwidth( ) , 8 ) ;
455+ assert_eq ! ( IntBounds { from: & IBig :: from( 20 ) , to: & IBig :: from( 257 ) } . bitwidth( ) , 9 ) ;
456+ assert_eq ! ( IntBounds { from: & IBig :: from( -256 ) , to: & IBig :: from( 256 ) } . bitwidth( ) , 9 ) ;
432457 assert_eq ! ( IntBounds { from: & IBig :: from( -1 ) , to: & IBig :: from( 1 ) } . bitwidth( ) , 1 ) ;
433458 assert_eq ! ( IntBounds { from: & IBig :: from( -2 ) , to: & IBig :: from( 1 ) } . bitwidth( ) , 2 ) ;
459+ assert_eq ! ( IntBounds { from: & IBig :: from( -2 ) , to: & IBig :: from( 2 ) } . bitwidth( ) , 2 ) ;
460+ assert_eq ! ( IntBounds { from: & IBig :: from( -3 ) , to: & IBig :: from( 2 ) } . bitwidth( ) , 3 ) ;
461+ assert_eq ! ( IntBounds { from: & IBig :: from( -2 ) , to: & IBig :: from( 3 ) } . bitwidth( ) , 3 ) ;
434462 assert_eq ! ( IntBounds { from: & IBig :: from( -1 ) , to: & IBig :: from( 2 ) } . bitwidth( ) , 2 ) ;
435463 assert_eq ! ( IntBounds { from: & IBig :: from( -2 ) , to: & IBig :: from( 3 ) } . bitwidth( ) , 3 ) ;
436464 assert_eq ! ( IntBounds { from: & IBig :: from( 2 ) , to: & IBig :: from( 9 ) } . bitwidth( ) , 4 ) ;
437465 assert_eq ! ( IntBounds { from: & IBig :: from( -1000 ) , to: & IBig :: from( 1 ) } . bitwidth( ) , 11 ) ;
438466 assert_eq ! ( IntBounds { from: & IBig :: from( -2000 ) , to: & IBig :: from( -999 ) } . bitwidth( ) , 12 ) ;
439- assert_eq ! ( IntBounds { from: & IBig :: from( -256 ) , to: & IBig :: from( 256 ) } . bitwidth( ) , 9 ) ;
440- assert_eq ! ( IntBounds { from: & IBig :: from( 0 ) , to: & IBig :: from( 256 ) } . bitwidth( ) , 8 ) ;
441- assert_eq ! ( IntBounds { from: & IBig :: from( 20 ) , to: & IBig :: from( 257 ) } . bitwidth( ) , 9 ) ;
442- assert_eq ! ( IntBounds { from: & IBig :: from( 0 ) , to: & IBig :: from( 1 ) } . bitwidth( ) , 0 ) ; // Zero sized wires are now possible
443467 }
444468}
0 commit comments