Побитовый сдвиг

388
26 января 2017, 04:51

Здравствуйте! Пишу скрипт на 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, учитывая что начальное значение и индекс в таблице неизвестно, известно только последнее значение.

Answer 1

Как работает побитовый сдвиг.

Рассмотрим совсем простой случай, для одного беззнакового байта и без переполнений.

Допустим есть у нас 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 с возможной потерей точности

READ ALSO
Генерация sitemap.xml в Wordpress без плагина

Генерация sitemap.xml в Wordpress без плагина

Как генерировать sitemapxml в Wordpress без плагина? Подскажите в каком направлении двигаться

369
Добавить автопрокрутку на слайдер

Добавить автопрокрутку на слайдер

У меня вот такой вопрос, как на этом слайдере сделать автопрокрутку?

649
Sources моего сайта,

Sources моего сайта,

Не понимаю, что за папки подключаются к сайту, который я делаю? Эти скрипты я не прописывал и зачем загружаются - не ясно, что делают - не понятноНужны...

341