【问题标题】:Binary representation of the 32 bits integer32 位整数的二进制表示
【发布时间】:2018-03-17 19:07:01
【问题描述】:

我是 c 编程的新手,我正在尝试更多地了解位,二进制 e.c.t

例如,我有三个 int 变量 m1 =255 或 11111111 二进制; m2 = 255 或 11111111 二进制,m3 = 255 或 11111111 二进制和 m4 = 0 或 00000000。我试图将所有主题放在单个 int 变量 temp 中。像这样的东西(11111111 11111111 11111111 00000000) 这是我拥有的一段代码:

int x1;  
unsigned char x2;  
unsigned char x3;
unsigned char x4;
int temp;
        x1 = x1|m1;
        printf("x1:%d\n", x1);
        x2 = x2|m2;
        printf("x2:%d\n", x2);
        temp = x1<<8;
        printf("temp:%d\n", temp);
        temp = temp|x2;
        printf("temp:%d\n", temp);
        x3 = x3|m3;
        printf("x3:%d\n", x3);
        temp = temp<<8;
        printf("temp:%d\n", temp);
        temp = temp|x3;
        printf("temp:%d\n", temp);
        x4 = x4|m4;
        printf("x4:%d\n", x4);
        temp = temp<<8;
        printf("temp:%d\n", x1);
        temp = temp|x4;
        printf("%d\n", temp);

我在这里使用左移和 OR 运算符。但是我得到了一些奇怪的输出。 (我打印了每一步以找出问题所在)。

我得到了下一个输出:

x1:255

x2:255

温度:65280

温度:65535

x3:255

温度:16776960

温度:16777215

x4:0

温度:-256

温度:-256

一切都很好,直到温度变为-256,我不知道为什么。 我很感激任何帮助!谢谢!

【问题讨论】:

  • 您似乎将unsigned char 打印为整数("%d" 说明符);您是否尝试过正确的说明符,例如"%c""%u"?
  • x1 = x1|m1; 你在声明后还没有初始化 x1。你在哪里声明了 m1?
  • 请贴出真实代码。无论如何,m1 甚至都没有声明,而您使用 x1 的未初始化值
  • @Evert %dunsigned char 的正确格式说明符(假设我们使用的是 8 位字符的系统)。这是因为默认参数提升将unsigned char 提升为int

标签: c binary int


【解决方案1】:

您在 C 语言中确实有几个选择。首先,您似乎正在尝试做以下事情。 (注意:您应该包含stdint.h 并使用uint32_t 保证宽度值而不是int)您的问题围绕通过OR'ing 未初始化的值 调用未定义的行为,并且未能正确转换 x1, ..., x4 的值。

要做你想做的事情,你可以:

#include <stdio.h>

int main (void) {

    unsigned int x1 = 0, x2 = 0, x3 = 0, x4 = 0;  
    unsigned char m1, m2, m3, m4 = 0;

    m1 = m2 = m3 = 255;

    x1 |= m1;
    x2 |= ((unsigned)m2 << 8);
    x3 |= ((unsigned)m3 << 16);
    x4 = ((x1 | x2 | x3) << 8) | (unsigned)m4;

    printf("x1: %u\n", x1);
    printf("x2: %u\n", x2);
    printf("x3: %u\n", x3);
    printf("x4: %u\n", x4);

    return 0;
}

使用/输出示例

$ ./bin/shiftx
x1: 255
x2: 65280
x3: 16711680
x4: 4294967040

您还可以通过简单地使用两个变量和值255 来简化逻辑。本质上,您将 temp 变量设置为 255 并左移 8、3 次。您的最终值是前 3 个临时值的 OR'ing,最后移位 8 以获得具有最低有效字节零的组合值,例如

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

int main (void) {

    uint32_t tmp = 0, val = 0;  
    uint8_t m = 255;

    val = m;
    printf ("tmp1 : %u\n", val);

    tmp = val << 8;
    printf ("tmp2 : %u\n", tmp);
    val |= tmp;

    tmp <<= 8;
    printf ("tmp3 : %u\n", tmp);
    val |= tmp;

    tmp <<= 8;
    printf ("tmp4 : %u\n", tmp);

    val <<= 8;
    printf ("val  : %u\n", val);

    return 0;
}

使用/输出示例

$ ./bin/shift1var
tmp1 : 255
tmp2 : 65280
tmp3 : 16711680
tmp4 : 4278190080
val  : 4294967040

改进的版本可以在bitfield structuint32_t 值之间使用union,保证32-bit 的宽度与架构无关。例如,您可以:

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

typedef union {
    struct {
        uint32_t a : 8,
                 b : 8,
                 c : 8,
                 d : 8;
    } bits;
    uint32_t value;
} bitunion;

int main (void) {

    bitunion bu = { .bits = {.a = 0, .b = 255, .c = 255, .d = 255} };

    printf ("bu.bits.a: %u\n", bu.bits.a);
    printf ("bu.bits.b: %u\n", bu.bits.b << 8);
    printf ("bu.bits.c: %u\n", bu.bits.c << 16);
    printf ("bu.bits.d: %u\n", bu.bits.d << 24);
    printf ("value    : %u\n", bu.value);     

    return 0;
}

注意:位域由d-c-b-a字节组成)

使用/输出示例

$ ./bin/shiftxstruct
bu.bits.a: 0
bu.bits.b: 65280
bu.bits.c: 16711680
bu.bits.d: 4278190080
value    : 4294967040

现在,不要认为这些是唯一的方法。只要您准确计算最终值中的字节数,就可以使用移位和 OR 的任意组合。如果您有其他问题,请查看并告诉我。

【讨论】:

    【解决方案2】:

    您正在使用 %d 格式并将变量视为有符号整数,您需要使用 %u 并将变量类型更改为无符号。

    unsigned char x1;
    unsigned int temp;
    

    【讨论】:

    • 谢谢,真的很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 2015-01-21
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多