Если 16-разрядное отрицательное целое число было сохранено в uint16_t
, называемом x
, то исходное значение может быть рассчитано как x-65536
.
. Может быть напечатано любое из 1 :
printf("%ld", x-65536L);
printf("%d", (int) (x-65536));
int y = x-65536;
printf("%d", y);
Вычитание 65536 работает, потому что:
- Согласно C 2018 6.5.16.1 2, значение правого операнда (отрицательное 16-разрядное целое число равнопреобразуется в тип выражения присваивания (который по сути является типом левого операнда).
- Согласно 6.3.1.3 2, преобразование в целое число без знака выполняется путем сложения или вычитания «на единицу больше максимального значениякоторый может быть представлен в новом типе ». Для
uint16_t
на единицу больше, чем его максимум составляет 65536. - С 16-разрядным отрицательным целым числом добавление 65536 один раз приводит его к диапазону
uint16_t
. - Следовательно, вычитание 65536 восстанавливает исходное значение.
Сноска
1 65536
будет long
или int
в зависимости от того, равен int
16 бит или более, поэтому эти операторы являютсяПравильно обращаться с типом правильно.Первый использует 65536L
, чтобы гарантировать тип long
.Остальные преобразуют значение в int
.Это безопасно, потому что, хотя тип x-65536
может быть long
, его значение вписывается в int
- если вы не выполняете в реализации C, которая ограничивает int
от -32767 до +32767, и оригиналзначение может быть -32768, в этом случае вам следует придерживаться первого варианта.