Skip to content

Commit 29cfed4

Browse files
jorgecarleitaokszucs
authored andcommitted
ARROW-11311: [Rust] Fixed unset_bit
The functions `unset_bit` and `unset_bit_raw` were toggling, not unsetting, bits, which was obviously wrong. This PR also changes the test for `set_bit` to also make sure that it does not toggle bits. Closes #9257 from jorgecarleitao/fix_unset Authored-by: Jorge C. Leitao <[email protected]> Signed-off-by: Andrew Lamb <[email protected]>
1 parent 15cebca commit 29cfed4

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

rust/arrow/src/util/bit_util.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@
2121
use packed_simd::u8x64;
2222

2323
const BIT_MASK: [u8; 8] = [1, 2, 4, 8, 16, 32, 64, 128];
24+
const UNSET_BIT_MASK: [u8; 8] = [
25+
255 - 1,
26+
255 - 2,
27+
255 - 4,
28+
255 - 8,
29+
255 - 16,
30+
255 - 32,
31+
255 - 64,
32+
255 - 128,
33+
];
2434

2535
/// Returns the nearest number that is `>=` than `num` and is a multiple of 64
2636
#[inline]
@@ -72,7 +82,7 @@ pub unsafe fn set_bit_raw(data: *mut u8, i: usize) {
7282
/// Sets bit at position `i` for `data` to 0
7383
#[inline]
7484
pub fn unset_bit(data: &mut [u8], i: usize) {
75-
data[i >> 3] ^= BIT_MASK[i & 7];
85+
data[i >> 3] &= UNSET_BIT_MASK[i & 7];
7686
}
7787

7888
/// Sets bit at position `i` for `data` to 0
@@ -83,7 +93,7 @@ pub fn unset_bit(data: &mut [u8], i: usize) {
8393
/// responsible to guarantee that `i` is within bounds.
8494
#[inline]
8595
pub unsafe fn unset_bit_raw(data: *mut u8, i: usize) {
86-
*data.add(i >> 3) ^= BIT_MASK[i & 7];
96+
*data.add(i >> 3) &= UNSET_BIT_MASK[i & 7];
8797
}
8898

8999
/// Returns the ceil of `value`/`divisor`
@@ -184,24 +194,24 @@ mod tests {
184194

185195
#[test]
186196
fn test_set_bit() {
187-
let mut b = [0b00000000];
197+
let mut b = [0b00000010];
188198
set_bit(&mut b, 0);
189-
assert_eq!([0b00000001], b);
190-
set_bit(&mut b, 2);
191-
assert_eq!([0b00000101], b);
192-
set_bit(&mut b, 5);
193-
assert_eq!([0b00100101], b);
199+
assert_eq!([0b00000011], b);
200+
set_bit(&mut b, 1);
201+
assert_eq!([0b00000011], b);
202+
set_bit(&mut b, 7);
203+
assert_eq!([0b10000011], b);
194204
}
195205

196206
#[test]
197207
fn test_unset_bit() {
198-
let mut b = [0b11111111];
208+
let mut b = [0b11111101];
199209
unset_bit(&mut b, 0);
200-
assert_eq!([0b11111110], b);
201-
unset_bit(&mut b, 2);
202-
assert_eq!([0b11111010], b);
203-
unset_bit(&mut b, 5);
204-
assert_eq!([0b11011010], b);
210+
assert_eq!([0b11111100], b);
211+
unset_bit(&mut b, 1);
212+
assert_eq!([0b11111100], b);
213+
unset_bit(&mut b, 7);
214+
assert_eq!([0b01111100], b);
205215
}
206216

207217
#[test]

0 commit comments

Comments
 (0)