2

说我有以下内容:

int32 a = ...; // value of variable irrelevant; can be negative
unsigned char *buf = malloc(4); /* assuming octet bytes, this is just big 
                          enough to hold an int32 */

是否有一种高效且可移植的算法以可移植的方式将二进制补码 big-endian 表示写入a4 字节缓冲区buf?也就是说,无论我们运行的机器如何在内部表示整数,我怎样才能有效地将二进制补码表示写入a缓冲区?

这是一个C问题,因此您可以依靠C标准来确定您的答案是否满足可移植性要求。

4

3 回答 3

2

是的,你当然可以便携地做到这一点:

int32_t a = ...;
uint32_t b = a;
unsigned char *buf = malloc(sizeof a);

uint32_t mask = (1U << CHAR_BIT) - 1;  // one-byte mask

for (int i = 0; i < sizeof a; i++)
{
    int shift = CHAR_BIT * (sizeof a - i - 1); // downshift amount to put next
                                               // byte in low bits
    buf[i] = (b >> shift) & mask;  // save current byte to buffer
}

至少,我认为这是对的。我会做一个快速测试。

于 2013-08-15T04:20:38.870 回答
2
unsigned long tmp = a; // Converts to "twos complement"
unsigned char *buf = malloc(4);
buf[0] = tmp>>24 & 255;
buf[1] = tmp>>16 & 255;
buf[2] = tmp>>8 & 255;
buf[3] = tmp & 255;

& 255如果您假设,您可以放下零件CHAR_BIT == 8

于 2013-08-15T04:21:13.663 回答
0

如果我理解正确,你想int32在一个 char 缓冲区内存储 4 个字节,以特定的顺序(例如低字节优先),不管如何int32表示。

让我们首先弄清楚这些假设:sizeof(char)=8、two'scomplement 和 sizeof(int32)=4。

不,您的代码中没有可移植的方式,因为您试图将其转换charunsigned char. 存储一个字节char是实现定义的。

但是,如果将其存储在unsigned char数组中,则有可移植的方式。您可以每次将值右移 8 位,以在结果数组中形成一个字节,或者使用按位和运算符 &:

// a is unsigned
1st byte = a & 0xFF
2nd byte = a>>8 & 0xFF
3rd byte = a>>16 & 0xFF
4th byte = a>>24 & 0xFF
于 2013-08-15T04:17:52.647 回答