【问题标题】:Convert unsigned integer to 48 bit binary in C在C中将无符号整数转换为48位二进制
【发布时间】:2017-09-12 15:40:12
【问题描述】:

我想将一个无符号整数转换为一个 48 位二进制表示的数组,如果结果小于 48 位,那么我需要将其余位归零。函数如下:

char *getBinary(unsigned int num)
{
char* bstring;
int i;
bstring = (char*) malloc(sizeof(char) * 49);
assert(bstring != NULL);

bstring[48] = '\0';
for( i = 0; i < 48; i++ )
{
    bstring[48 - 1 - i] = (num == ((1 << i) | num)) ? '1' : '0';
}
return bstring;
}

在主函数中:

unsigned int nbr1=3213816984;
char * bi=getBinary(nbr1);

结果应该是:

000000000000000010111111100011101111010010011000

但我得到了:

111101001001100010111111100011101111010010011000

为什么我不能将超过 32 位的位清零?

【问题讨论】:

  • 因为unsigned int num 是一个 32 位的数量。在转换之前,您必须转换为 64 位数量,例如 unsigned long long
  • @JonathanLeffler 您好,感谢您的回复!我尝试使用 unsigned long long 但仍然得到相同的结果。
  • 您必须更改函数的接口,以便它接受 64 位(或大于 32 位)的值 — 在任何正常情况下,您基本上不会获得超过 32 位的值平台。 1 &lt;&lt; i 中的 1 也是 int,因此是 32 位的。您可能需要在那里使用1ULL &lt;&lt; i。此外,num == ((1ULL &lt;&lt; i) | num) 可能没有做你想做的事。您可能需要((1ULL &lt;&lt; i) &amp; num) != 0 或附近。
  • 嗨,非常感谢我尝试了 num == ((1ULL
  • 嗯...这是一个不寻常的成语(我不记得以前见过),但我猜num == ((1ULL &lt;&lt; i) | num) 确实有效。它检查num 在您设置数字中的第 i 位时不会改变。 num &amp; (1ULL &lt;&lt; i) 表示法从数字中提取第 i 位——因此我编写了替代测试。

标签: c arrays binary bit-manipulation decimal


【解决方案1】:

您在未定义中调用的行为。 也就是说,C 标准没有规定当您将数字移动到比其默认位宽更远时会发生什么。所以编译器编写者可以为所欲为。

在您的示例中,行为似乎是“环绕”该位,使得 1

正如@Jonathan Leffler 在评论中提到的,您需要使用足够宽的数据类型来支持您的 48 位方案,或者您需要采取措施将 48 位输入分解为 32 位片段,随你喜欢。

编辑:

根据您的评论,我将指出 1 是一个整数文字。它有一个类型。所以表达式1 &lt;&lt; i的结果也有一个类型,它是从1的类型派生而来的。

如果您想对 unsigned-long-long 数字进行操作,最好的办法是尽快将所有内容放入一些正确类型的变量中。

unsigned long long ONE = 1;

ONE << i

替代方案 - 使用常量文字 - 涉及 ULL 后缀:

1ULL << i

【讨论】:

    猜你喜欢
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 2018-03-01
    • 2021-03-09
    相关资源
    最近更新 更多