#c #типы_данных #системы_счисления
Разрабатывал спецификатор %x с помощью двоичных тетрад. После чего решил расширить функционал до %llx. Но не тут то было! По каким-то причинам программа работала не верно. Решил рассмотреть побитовое представление числа в формате long long unsigned. В итоге обнаружил, что, например 32 бит числа 1 равен 1. Почему так? Собственно сабж: #include#include int checkbit(unsigned long long value, int position) { return ((value & (1 << position)) != 0); } int main (void) { unsigned long long num = 1; for (int i = 0; i < sizeof(unsigned long long) * CHAR_BIT; i++) printf("%d = %d\n", i, checkbit(num, i)); return 0; } Результат: 0 = 1 1 = 0 2 = 0 3 = 0 4 = 0 5 = 0 6 = 0 7 = 0 8 = 0 9 = 0 10 = 0 11 = 0 12 = 0 13 = 0 14 = 0 15 = 0 16 = 0 17 = 0 18 = 0 19 = 0 20 = 0 21 = 0 22 = 0 23 = 0 24 = 0 25 = 0 26 = 0 27 = 0 28 = 0 29 = 0 30 = 0 31 = 0 32 = 1 33 = 0 34 = 0 35 = 0 36 = 0 37 = 0 38 = 0 39 = 0 40 = 0 41 = 0 42 = 0 43 = 0 44 = 0 45 = 0 46 = 0 47 = 0 48 = 0 49 = 0 50 = 0 51 = 0 52 = 0 53 = 0 54 = 0 55 = 0 56 = 0 57 = 0 58 = 0 59 = 0 60 = 0 61 = 0 62 = 0 63 = 0
Ответы
Ответ 1
Всё дело в строке 1 << position Литерал 1 имеет тип int, который, на вашей платформе имеет размер, меньший, чем unsigned long long, и при position >= sizeof(int) * CHAR_BIT результат сдвига не может быть представлен в типе int, поэтому возникает неопределенное поведение. Из стандарта C++14: Otherwise, if E1 has a signed type and non-negative value, and E1×2^E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined. Из стандарта C11: If E1 has a signed type and nonnegative value, and E1 × 2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined. Исправление: (1ull << position)
Комментариев нет:
Отправить комментарий