2

时间:2018-12-01 04:55:34

标签: c types binary

我在解释存储在计算机内存中的数字的二进制读数时遇到问题。

我写了一个小program,它取一个整数,浮点数或字符串,并打印存储在内存中的二进制数。

此后,我想观看十进制和二进制之间的关系。这导致2的幂从0到64的迭代。要打印二进制部分,我使用了上面程序的一部分。我发现对我来说很奇怪,而且我很难理解为什么系统会按原样存储数字。

这是我的困惑: 对于每次迭代,程序将打印3个数字的十进制和二进制版本,如下所示:

  • 1 << i:
  • 1 << i-1:
  • 1 << i(所有较小的位也都设置为1):

当程序达到30时,这是6个输出: 30: 1073741824 30: 1073741823 30: 2147483647 00000000 00000000 00000000 01000000 00000000 00000000 00000000 00000000 11111111 11111111 11111111 00111111 00000000 00000000 00000000 00000000 11111111 11111111 11111111 01111111 00000000 00000000 00000000 00000000

在31岁时发生: 31: 18446744071562067968 31: 2147483647 31: 18446744073709551615 00000000 00000000 00000000 10000000 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01111111 00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111

在32岁时: 32: 1 32: 0 32: 18446744073709551615 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111

请求

有人可以帮助我解释这些发现,包括解释为什么直到达到18446744073709551615(2 ^ 64-1)时钻头仍不能很好地移动?

(我也欢迎您对该程序提出任何建议。)

参考

所以您可以在家玩,这是它给我的程序和输出:

参考计划

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>

void dtob(char *num, size_t size)
{
    int i;
    bool binary;

    for ( ; size; size--, num++) {
        for (i = 7; i > -1; i--) {
            binary = *num & (1 << i);
            printf("%d", binary);

        }
        printf(" ");
    }
    printf("\n");
}

int main(void)
{
    int i;

    uintmax_t num1 = 0;
    uintmax_t num2 = 0;
    uintmax_t num3 = 0;

    void *ptr1;
    void *ptr2;
    void *ptr3;

    ptr1 = &num1;
    ptr2 = &num2;
    ptr3 = &num3;

    for (i = 0; i < 65; i++) {
        num1 = (1 << i);
        num2 = (1 << i) - 1;
        num3 |= (1 << i);

        printf("%d: %ju\n", i, num1);
        printf("%d: %ju\n", i, num2);
        printf("%d: %ju\n", i, num3);

        dtob(ptr1, sizeof(uintmax_t));
        dtob(ptr2, sizeof(uintmax_t));
        dtob(ptr3, sizeof(uintmax_t));
    }

    return 0;
}

参考输出:

0: 1
0: 0
0: 1
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
1: 2
1: 1
1: 3
00000010 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000011 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
2: 4
2: 3
2: 7
00000100 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000011 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
3: 8
3: 7
3: 15
00001000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00001111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
4: 16
4: 15
4: 31
00010000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00001111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00011111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
5: 32
5: 31
5: 63
00100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00011111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
6: 64
6: 63
6: 127
01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
01111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
7: 128
7: 127
7: 255
10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
01111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
8: 256
8: 255
8: 511
00000000 00000001 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000001 00000000 00000000 00000000 00000000 00000000 00000000 
9: 512
9: 511
9: 1023
00000000 00000010 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000001 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000011 00000000 00000000 00000000 00000000 00000000 00000000 
10: 1024
10: 1023
10: 2047
00000000 00000100 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000011 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000111 00000000 00000000 00000000 00000000 00000000 00000000 
11: 2048
11: 2047
11: 4095
00000000 00001000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00001111 00000000 00000000 00000000 00000000 00000000 00000000 
12: 4096
12: 4095
12: 8191
00000000 00010000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00001111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00011111 00000000 00000000 00000000 00000000 00000000 00000000 
13: 8192
13: 8191
13: 16383
00000000 00100000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00011111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00111111 00000000 00000000 00000000 00000000 00000000 00000000 
14: 16384
14: 16383
14: 32767
00000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00111111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 01111111 00000000 00000000 00000000 00000000 00000000 00000000 
15: 32768
15: 32767
15: 65535
00000000 10000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 01111111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000 
16: 65536
16: 65535
16: 131071
00000000 00000000 00000001 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000001 00000000 00000000 00000000 00000000 00000000 
17: 131072
17: 131071
17: 262143
00000000 00000000 00000010 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000001 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000011 00000000 00000000 00000000 00000000 00000000 
18: 262144
18: 262143
18: 524287
00000000 00000000 00000100 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000011 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000111 00000000 00000000 00000000 00000000 00000000 
19: 524288
19: 524287
19: 1048575
00000000 00000000 00001000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00001111 00000000 00000000 00000000 00000000 00000000 
20: 1048576
20: 1048575
20: 2097151
00000000 00000000 00010000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00001111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00011111 00000000 00000000 00000000 00000000 00000000 
21: 2097152
21: 2097151
21: 4194303
00000000 00000000 00100000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00011111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00111111 00000000 00000000 00000000 00000000 00000000 
22: 4194304
22: 4194303
22: 8388607
00000000 00000000 01000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00111111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 01111111 00000000 00000000 00000000 00000000 00000000 
23: 8388608
23: 8388607
23: 16777215
00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 01111111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 
24: 16777216
24: 16777215
24: 33554431
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000001 00000000 00000000 00000000 00000000 
25: 33554432
25: 33554431
25: 67108863
00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000001 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000011 00000000 00000000 00000000 00000000 
26: 67108864
26: 67108863
26: 134217727
00000000 00000000 00000000 00000100 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000011 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000111 00000000 00000000 00000000 00000000 
27: 134217728
27: 134217727
27: 268435455
00000000 00000000 00000000 00001000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00001111 00000000 00000000 00000000 00000000 
28: 268435456
28: 268435455
28: 536870911
00000000 00000000 00000000 00010000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00001111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00011111 00000000 00000000 00000000 00000000 
29: 536870912
29: 536870911
29: 1073741823
00000000 00000000 00000000 00100000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00011111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00111111 00000000 00000000 00000000 00000000 
30: 1073741824
30: 1073741823
30: 2147483647
00000000 00000000 00000000 01000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00111111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 01111111 00000000 00000000 00000000 00000000 
31: 18446744071562067968
31: 2147483647
31: 18446744073709551615
00000000 00000000 00000000 10000000 11111111 11111111 11111111 11111111 
11111111 11111111 11111111 01111111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
32: 1
32: 0
32: 18446744073709551615
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
33: 2
33: 1
33: 18446744073709551615
00000010 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
34: 4
34: 3
34: 18446744073709551615
00000100 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000011 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
35: 8
35: 7
35: 18446744073709551615
00001000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
36: 16
36: 15
36: 18446744073709551615
00010000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00001111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
37: 32
37: 31
37: 18446744073709551615
00100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00011111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
38: 64
38: 63
38: 18446744073709551615
01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
39: 128
39: 127
39: 18446744073709551615
10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
01111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
40: 256
40: 255
40: 18446744073709551615
00000000 00000001 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
41: 512
41: 511
41: 18446744073709551615
00000000 00000010 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000001 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
42: 1024
42: 1023
42: 18446744073709551615
00000000 00000100 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000011 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
43: 2048
43: 2047
43: 18446744073709551615
00000000 00001000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00000111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
44: 4096
44: 4095
44: 18446744073709551615
00000000 00010000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00001111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
45: 8192
45: 8191
45: 18446744073709551615
00000000 00100000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00011111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
46: 16384
46: 16383
46: 18446744073709551615
00000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 00111111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
47: 32768
47: 32767
47: 18446744073709551615
00000000 10000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 01111111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
48: 65536
48: 65535
48: 18446744073709551615
00000000 00000000 00000001 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
49: 131072
49: 131071
49: 18446744073709551615
00000000 00000000 00000010 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000001 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
50: 262144
50: 262143
50: 18446744073709551615
00000000 00000000 00000100 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000011 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
51: 524288
51: 524287
51: 18446744073709551615
00000000 00000000 00001000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00000111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
52: 1048576
52: 1048575
52: 18446744073709551615
00000000 00000000 00010000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00001111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
53: 2097152
53: 2097151
53: 18446744073709551615
00000000 00000000 00100000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00011111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
54: 4194304
54: 4194303
54: 18446744073709551615
00000000 00000000 01000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 00111111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
55: 8388608
55: 8388607
55: 18446744073709551615
00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 01111111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
56: 16777216
56: 16777215
56: 18446744073709551615
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
57: 33554432
57: 33554431
57: 18446744073709551615
00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000001 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
58: 67108864
58: 67108863
58: 18446744073709551615
00000000 00000000 00000000 00000100 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000011 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
59: 134217728
59: 134217727
59: 18446744073709551615
00000000 00000000 00000000 00001000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00000111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
60: 268435456
60: 268435455
60: 18446744073709551615
00000000 00000000 00000000 00010000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00001111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
61: 536870912
61: 536870911
61: 18446744073709551615
00000000 00000000 00000000 00100000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00011111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
62: 1073741824
62: 1073741823
62: 18446744073709551615
00000000 00000000 00000000 01000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 00111111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
63: 18446744071562067968
63: 2147483647
63: 18446744073709551615
00000000 00000000 00000000 10000000 11111111 11111111 11111111 11111111 
11111111 11111111 11111111 01111111 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
64: 1
64: 0
64: 18446744073709551615
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 

先谢谢您! 希尔德

1 个答案:

答案 0 :(得分:0)

代码超出了允许范围。

uintmax_t num1;
for (i = 0; i < 65; i++) {
    num1 = (1 << i);         // int overflow! UB

如果int是32位,则1 << 31未定义行为(UB),将1移到正号位。

1u情况下使用i==31可以避免这种情况。

unsigned为32位的情况下,UB的移位仍为32,33,34,...。

使用更宽的1,例如1LLU,至少应为64位。


代码仍超出允许范围。

uintmax_t num1;
for (i = 0; i < 65; i++) {
    num1 = (1LLU << i);  // trouble when i==64

如果unsigned long long是64位,则1LLU << 64是UB。

使用比1更宽的UINTMAX_C(1)可能可以超过64位,但在2018年不太可能。


故事的道德感

  • 确保整数数学满足目标对象的类型。

    uintmax_t num1;
    num1 = UINTMAX_C(1) << i;
    // or     
    uintmax_t one = 1;
    num1 = one << i;
    // or when `num1` has a value
    num1 = (num1*0 + 1) << i;  // let the compiler optimize
    
  • 不要移位超过字体宽度。