Здравствуйте! Пишу скрипт на php. Есть числа:
16359391
15382371
7177275
15318085
16431130
Пример чисел из программы, с каждым числом происходит >> 8 и получается число меньше, а когда делать побитовый сдвиг с результатом только << 8, значение с начальным не сходится. Скажите, как делать побитовый сдвиг без потери чисел и чтобы при сдвиге в одну из сторон число было длинной на 2 цифри меньше? или может есть какой-нибудь другой вариант? Самое главное в задаче это уменьшить данное число на 2 цифри и чтобы его можно обратно перевести в начальное число.
Должно получается примерно так для разных чисел:
16359391
63903
16359391
UPD:
Вот пример кода: Есть таблица
$table = array(
0x003b6c1c,
0x002def61,
0x006effa2,
0x0013045f,
0x00873358,
0x0039e1fd,
0x0061491a,
0x002608bf,
0x00254ed0,
0x004fc7dd,
0x00721a32,
0x0018dce3,
0x001328bc,
0x003e288d,
0x0084387e,
0x004c11e3);
$table_index = 13;
$b = 16359391;
$result = $b ^ $table[$table_index];
$resultfinal = ($result >> 8).$table_index;
И нужно с $resultfinal получить 16359391, учитывая что начальное значение и индекс в таблице неизвестно, известно только последнее значение.
Как работает побитовый сдвиг.
Рассмотрим совсем простой случай, для одного беззнакового байта и без переполнений.
Допустим есть у нас 1 байт равный FF. В двоичном представлении это будет 11111111
Сдвинем его вправо 11111111 >> 1 = 0111111. Крайняя правая единица при этом теряется. Насовсем. Как небыло. Сдвинем теперь получившееся число обратно, влево 01111111 << 1 = 11111110
Если первой операцией сдвигать влево, то совершенно по тому же принципу потеряется начальный бит.
Теперь про ваш случай. Так как PHP оперирует динамическим приведением типов, то можно(в разумных пределах) воспользоваться знанием о том, что побитовый сдвиг влево равнозначен умножению на 2 (на бесконечном количестве бит), а сдвиг вправо - равнозначен делению на два.
Т.е. для решения вашей задачи нужно использовать не сдвиг, а математические операции умножения и деления.
$a = 16359391;
$a_shifted = $a / (2*2*2*2*2*2*2*2); // аналогично $a >> 8
$a_unshifted = $a_shifted * (2*2*2*2*2*2*2*2); // аналогично $a_shifted << 8
Но тут надо понимать, что при этом у вас может произойти преобразование int в float с возможной потерей точности
Сборка персонального компьютера от Artline: умный выбор для современных пользователей