Арифметика против операции логического сдвига в C ++ - PullRequest
1 голос
/ 06 октября 2011

У меня есть код, который вставляет параметры различной длины (u8, u16, u32) в u64 с оператором сдвига влево.

Затем в разных местах кода мне нужно вернуть исходные параметры из этого большого раздутого параметра.

Просто интересно, как в коде мы должны гарантировать, что это логическое смещение вправо, а не арифметика, при возврате исходных параметров.

Итак, вопрос в том, существуют ли какие-либо #defs или другие способы гарантировать и проверять, не испортится ли компилятор?

Вот код C ++:

u32 x , y ,z;
u64 uniqID = 0;
u64 uniqID = (s64) x << 54 |
             (s64) y << 52 |
             (s64) z << 32 |
             uniqID;  // the original uniqID value.

и позже при получении значений обратно:

z= (u32) ((uniqID >> 32 ) & (0x0FFFFF)); //20 bits 
y= (u32) ((uniqID >> (52 ) & 0x03));     //2 bits
x= (u32) ((uniqID >> (54) & 0x03F));     //6 bits

Ответы [ 2 ]

1 голос
/ 06 октября 2011

Это похоже на C / C ++, поэтому просто убедитесь, что uniqID является целым типом без знака.

В качестве альтернативы просто разыграйте:

z = (u32) ( ((unsigned long long)uniqID >> (32) & (0x0FFFFF));  //20 bits 
y = (u32) ( ((unsigned long long)uniqID >> (52) & 0x03)) ; //2 bits
x = (u32) ( ((unsigned long long)uniqID >> (54) & 0x03F)) ;  //6 bits 
1 голос
/ 06 октября 2011

Общее правило: логический сдвиг подходит для двоичных чисел без знака, а арифметический сдвиг - для чисел со знаком 2.Это будет зависеть от вашего компилятора (gcc и т. Д.), А не столько от языка, но вы можете предположить, что компилятор будет использовать логическое смещение для чисел без знака ... Поэтому, если у вас есть тип без знака, можно подумать, что это будетлогический сдвиг.

Вы всегда можете написать свой собственный метод для проверки и переключения, если вам нужна переносимость между компиляторами.Или вы можете использовать встроенный asm для этого и избежать каких-либо проблем (но вы будете привязаны к платформе).

Короче, чтобы быть на 100% правильным, проверьте документацию вашего компилятора.

...