Есть ли более простой способ сделать это?
Да, используйте tmp var, он проще и может быть лучше оптимизирован компиляторами.
int tmp = num1;
num1 = num2;
num2 = tmp;
// this swaps the whole value, not just the low 8 bits
// if that's important, see below for bit-difference XOR
Это может иногда компилировать в ноль asm-инструкции; компилятор просто знает, где находится var. Почему люди не используют xor swap?
Возможен простой xor-swap всех значений, но вы никогда не должны использовать его, за исключением редких случаев в рукописном асме. В C всегда используйте вместо tmp var. Какой самый быстрый способ поменять значения в C? спрашивает о xor-swap против обычного swap. По некоторым причинам многие думают, что своп xor может быть более эффективным, и называют это «преждевременной оптимизацией». Это не. Это плохо для компиляторов, а также для людей. Если бы это было более эффективно на некоторой машине, оптимизирующие компиляторы скомпилировали бы нормальные подстановки в подстановки xor в asm; в этом смысл современного оптимизирующего компилятора.
Является ли мой алгоритм по своей сути ошибочным?
Для производительности да.
Для правильности, не ошибочно, но одна ошибка показывает . Вы проверяете бит в bitindex с помощью num1 & position
, , но вместо обмена этими битами вы используете num1 << bitindex
вместо 1 << bitindex
.
Самый первый шаг этого, с bitindex = 0
, обнулит оба числа, если одно нечетное, а другое четное (поэтому условие истинно, поскольку их младшие биты различаются). x^x == 0
для всех x.
// with bit-index = 0
num1 ^= (num1 << bitindex); // becomes num1 ^= num1
num2 ^= (num2 << bitindex); // becomes num2 ^= num2
Обычно использование сдвинутых num1 и num2 бесполезно.
Также обратите внимание, что ваш position
уже равен 1<<bitindex
, так что вы можете также просто используйте это, и у вас не будет bitindex
.
Вы пытаетесь реализовать обмен по битам, который очень неэффективен. Вы бы когда-нибудь сделали что-нибудь , например, , если бы вы хотели поменять местами только определенный диапазон бит, и вы все равно сделали бы все позиции битов, которые вы хотели, за один шаг, используя маску с эти биты установлены. (Вместо сдвига влево однобитовой маски в al oop.)
С Замена битов в заданной точке между двумя байтами , что объясняет, как работает этот алгоритм:
unsigned bitdiff = num1 ^ num2;
bitdiff &= 0xff; // only swap the low 8 bits
num1 ^= bitdiff;
num2 ^= bitdiff;
При замене вашего l oop он может поменять местами 4 и 7.
Или для более крупных входов, таких как 555
и 444
, мы получим 700
и 299
. (Это
0x22b, 0x1b c => 0x2b c, 0x12b, правильно меняющие младшие 8 бит)