@@ -3259,9 +3259,9 @@ impl BigInt {
3259
3259
/// uses the two's complement for negative numbers
3260
3260
pub fn bit ( & self , bit : u64 ) -> bool {
3261
3261
// Let the binary representation of a number be
3262
- // x 1 0 ... 0
3262
+ // ... 0 x 1 0 ... 0
3263
3263
// Then the two's complement is
3264
- // !x 1 0 ... 0
3264
+ // ... 1 !x 1 0 ... 0
3265
3265
// where !x is obtained from x by flipping each bit
3266
3266
let b = self . data . bit ( bit) ;
3267
3267
if self . is_negative ( ) && bit > self . data . trailing_zeros ( ) . unwrap ( ) {
@@ -3275,6 +3275,7 @@ impl BigInt {
3275
3275
match self . sign {
3276
3276
Sign :: Plus => self . data . set_bit ( bit, value) ,
3277
3277
Sign :: NoSign => {
3278
+ // clearing a bit for zero is a no-op
3278
3279
if value {
3279
3280
self . data . set_bit ( bit, true ) ;
3280
3281
self . sign = Sign :: Plus ;
@@ -3283,25 +3284,28 @@ impl BigInt {
3283
3284
Sign :: Minus => {
3284
3285
let bits_per_digit = u64:: from ( big_digit:: BITS ) ;
3285
3286
if bit < bits_per_digit * self . len ( ) as u64 {
3286
- let digit_index = ( bit / bits_per_digit) as usize ;
3287
+ // This implementation corresponds to what the function `bitand_neg_pos` does when
3288
+ // value=false and what `bitor_neg_pos` does when value=true, except there is no
3289
+ // need to explicitly iterate over the digits of the right-hand side
3290
+ let bit_index = ( bit / bits_per_digit) as usize ;
3287
3291
let bit_mask = ( 1 as BigDigit ) << ( bit % bits_per_digit) ;
3288
3292
let mut carry_in = 1 ;
3289
3293
let mut carry_out = 1 ;
3290
- for ( i, d) in self . digits_mut ( ) . iter_mut ( ) . enumerate ( ) {
3291
- let twos_in = negate_carry ( * d, & mut carry_in) ;
3292
- let twos_out = if i != digit_index {
3293
- // leave as-is
3294
+ for ( index, digit) in self . digits_mut ( ) . iter_mut ( ) . enumerate ( ) {
3295
+ let twos_in = negate_carry ( * digit, & mut carry_in) ;
3296
+ let twos_out = if index != bit_index {
3294
3297
twos_in
3295
3298
} else if value {
3296
- // set bit
3297
3299
twos_in | bit_mask
3298
3300
} else {
3299
- // clear bit
3300
3301
twos_in & !bit_mask
3301
3302
} ;
3302
- * d = negate_carry ( twos_out, & mut carry_out) ;
3303
+ * digit = negate_carry ( twos_out, & mut carry_out) ;
3303
3304
}
3304
3305
} else {
3306
+ // The bit to set/clear is outside the represented digits, and thus more significant
3307
+ // than the most significant bit of the current number. This corresponds to setting
3308
+ // the bit to the negated value (no-op for value=true)
3305
3309
if !value {
3306
3310
self . data . set_bit ( bit, true ) ;
3307
3311
}
0 commit comments