Я сейчас работаю над проектом, в котором мне нужны битовые наборы. Я использую массив uint64_t
для битового набора.C - BitArray - установить один бит uint64_t
Моя текущая проблема в том, что всякий раз, когда я хочу, чтобы установить или проверить бит мне нужно сделать операцию так:
uint64_t index = 42;
bArr[index/64] |= (((uint64_t)1)<<(index%64));
Я могу переписать деление и по модулю с некоторым умным и и bithift операций, но я обеспокоен литой 1
. Мне нужен этот прилив, поскольку в противном случае 1
рассматривается как 32-битный блок. Как видно из этого примера, вы получаете неправильный результат без литья:
uint64_t bArr[4]; // 256 bits
bArr[0] = bArr[1] = bArr[2] = bArr[3] = 0; // Set to 0
uint64_t i = 255;
bArr[i/64] = (bArr[i/64] | (((uint64_t)1)<<(i%64)));
uint32_t i2;
for (i2 = 0; i2 < 256; i2++) {
if ((bArr[i2/64] & (((uint64_t)1)<<(i2%64))) != 0) {
printf("bArray[%" PRIu32 "] = 1\n", i2);
}
}
Могу ли я обойти этот прилив умным способом? Я думал, что производительность, вероятно, страдает от броска на каждый читать/писать ...
Do * not * переписать раздел и по модулю быть «умным»; компилятор, безусловно, достаточно умен, чтобы уже сделать эти оптимизации для вас. Также рассмотрите использование 'CHAR_BIT * sizeof bArr [0]' вместо '64', чтобы избежать магических чисел. – unwind
@unwind Спасибо за подсказку. Я проверю его с помощью моего кода. Скорее всего, это так. – Matthias
Если вы ищете скорость, предоставьте таблицу 'const uint64_t' с 64 различными константами ULL (1 предварительно перемещенными во все возможные места) и проиндексируйте их. – tofro