Developed the %x specifier using binary tetrads. Then I decided to expand the functionality to %llx . But it was not there! For some reason, the program did not work correctly.

Decided to consider the bitwise representation of a long long unsigned . As a result, I found out that, for example, 32 bits of the number 1 is 1. Why is that?

Actually a subject:

 #include <stdio.h> #include <limits.h> 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; } 

Result:

 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 
  • 2
    Including precisely for this reason, we can offer (value >> position) & 1 as the recommended method for checking the value of a bit. The less in the expression of dependencies on specific types of arguments - the better. - AnT

1 answer 1

It's all about line 1 << position Literal 1 is of type int , which, on your platform, has a size smaller than unsigned long long , and with position >= sizeof(int) * CHAR_BIT result of the shift cannot be represented in type int therefore, undefined behavior occurs.

From the standard C ++ 14:

Otherwise, if E1 is a signed type and non-negative value, and E1 × 2 ^ E2 is a representation of the type, otherwise, the behavior is undefined.

From standard C11:

If E1 has a signed type and it is a non-negative value, and E1 × 2 ^ E2 is a representation of the result, then that is the resulting value; otherwise, the behavior is undefined.

Fix: (1ull << position)

  • one
    The quote you give is a quote from the C ++ language standard. In C, the requirements for shifting sign values ​​to the left are a little more stringent: "If you want, then you can’t get it; ". - wololo
  • @wololo while searching for the document, forgot that the question on C. Added to the answer and a quote from the standard C11. Thank. - Croessmah