как отменить битовую операцию в C - PullRequest
2 голосов
/ 07 мая 2020

У меня есть следующая C программа, которая теперь получит MSB, 2nd MSB, 3rd MSB и LSB для значения 1588800373). Как мне отменить это? То есть, если в программе есть time_0 = 94, time_1 = 179, time_2 = 43, time_3 = 117, как мне построить ее обратно в now = 1588800373;

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

int main()
{
  time_t now = 1588800373; //time(NULL);
  uint8_t time_0 = now >> 24;
  uint8_t time_1 = (now >> 16) & 0xFF;
  uint8_t time_2 = (now >> 8) & 0xFF;
  uint8_t time_3 = now & 0xFF;

  printf("%lu, %u, %u, %u, %u\n", now, time_0, time_1, time_2, time_3);
  // 1588800373, 94, 179, 43, 117

  return 0;
}

1 Ответ

2 голосов
/ 07 мая 2020

Сдвиньте байты, используя по крайней мере 32-битную математику без знака, а затем |.

uint32_t repacked = ((uint32_t)time_0 << 24) | ((uint32_t)time_1 << 16) | 
    ((uint32_t)time_2 << 8) | time_3;
time_t now_again = (time_t) repacked;

time_0 << 24 само по себе преобразует time_0 в int, а затем сдвигает. Это может перейти в знаковый бит int и является поведением undefined . На небольших платформах с 16-int тоже UB сдвигать 16 или больше. Используйте достаточно широкий беззнаковый шрифт.


Исходный код подвержен ошибке y2038 должен time_t кодировать как 32-битный подписанный int. Лучше сначала взять time_t в uint32_t, а затем разделить / сдвинуть на 4 байта.

...