C 写入两个'的算法;s可移植地在内存中补码整数

C 写入两个'的算法;s可移植地在内存中补码整数,c,bit-manipulation,twos-complement,data-representation,C,Bit Manipulation,Twos Complement,Data Representation,假设我有以下几点: 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 */ 是否有一种高效且可移植的算法可以将a的两个补码大端表示以可移植的方式写入4字节缓冲区buf?也

假设我有以下几点:

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 */
是否有一种高效且可移植的算法可以将a的两个补码大端表示以可移植的方式写入4字节缓冲区
buf
?也就是说,无论我们正在运行的机器如何在内部表示整数,我如何有效地将
a
的两个补码表示写入缓冲区


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

如果我理解正确,您希望在字符缓冲区内按特定顺序(例如,先存储较低字节)存储4个字节的
int32
,无论如何表示
int32

首先让我们明确一下这些假设:sizeof(char)=8,表示两个人的赞美,sizeof(int32)=4

不,代码中没有可移植的方式,因为您试图将其转换为
char
,而不是
无符号char
。在
char
中存储字节是实现定义的

但如果将其存储在
无符号字符
数组中,则有一些可移植的方法。您可以将该值每次右移8位,以在结果数组中形成一个字节,或使用按位and运算符&:

// a is unsigned
1st byte = a & 0xFF
2nd byte = a>>8 & 0xFF
3rd byte = a>>16 & 0xFF
4th byte = a>>24 & 0xFF

如果我理解正确,您希望在char缓冲区中以特定顺序(例如,先低字节)存储4个字节的
int32
,而不管
int32
是如何表示的

首先让我们明确一下这些假设:sizeof(char)=8,表示两个人的赞美,sizeof(int32)=4

不,代码中没有可移植的方式,因为您试图将其转换为
char
,而不是
无符号char
。在
char
中存储字节是实现定义的

但如果将其存储在
无符号字符
数组中,则有一些可移植的方法。您可以将该值每次右移8位,以在结果数组中形成一个字节,或使用按位and运算符&:

// a is unsigned
1st byte = a & 0xFF
2nd byte = a>>8 & 0xFF
3rd byte = a>>16 & 0xFF
4th byte = a>>24 & 0xFF

是的,您当然可以随身携带:

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
}
int32_t a=。。。;
uint32_t b=a;
无符号字符*buf=malloc(sizeof a);
uint32_t mask=(1U>shift)&mask;//将当前字节保存到缓冲区
}

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

是的,你当然可以随身携带:

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
}
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;
int32_t a=。。。;
uint32_t b=a;
无符号字符*buf=malloc(sizeof a);
uint32_t mask=(1U>shift)&mask;//将当前字节保存到缓冲区
}
至少,我认为这是对的。我要做个快速测试

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;
如果假设
字符位==8
,则可以删除
&255
部分



如果假设
字符位==8

使用int而不是int32,则可以删除
&255
部分。我相信int是2的赞美。此外,只有当您与另一台传递INTEGER数据的计算机通话时,endianess才起作用。如果这是一个问题,那么你必须对这台机器做一个持久性检查,看看它是否兼容。在char
1
中通过passin执行该操作,并让他们向您发送
1
的int值。这有意义吗?@PaulNikonowicz:C标准不要求
int
是二的补充。在这种情况下,endianness确实很重要,因为我们讨论的是将整数写入字符缓冲区,我们不希望数字“向后”写入。字符缓冲区可以消除endianness问题。@PaulNikonowicz,这是什么意思?如果是多字节类型,则必须选择一个或另一个endianness。我们正在将4字节整数的表示形式写入4字节数组,因此endianness显然是一个问题。请使用int而不是int32。我相信int是2的赞美。此外,只有当您与另一台传递INTEGER数据的计算机通话时,endianess才起作用。如果这是一个问题,那么你必须对这台机器做一个持久性检查,看看它是否兼容。在char
1
中通过passin执行该操作,并让他们向您发送
1
的int值。这有意义吗?@PaulNikonowicz:C标准不要求
int
是二的补充。在这种情况下,endianness确实很重要,因为我们讨论的是将整数写入字符缓冲区,我们不希望数字“向后”写入。字符缓冲区可以消除endianness问题。@PaulNikonowicz,这是什么意思?如果您有多字节类型,则必须选择一个或另一个endianness。我们正在将4字节整数的表示形式写入4字节数组,因此endianness显然是一个问题。实际上是实现定义的,而不是未定义的。如果
char
是无符号类型,则可以。@R。。对的是的,我想假设sizeof(int32)==4,CHAR_位==8。
char
是一个输入错误,我的意思是
unsigned char
。实际上是实现定义的,而不是未定义的。如果
char
是一个unsigned类型,就可以了。@R。。对的是的,我想假设sizeof(int32)==4,CHAR_位==8。
char
是一个打字错误,我的意思是
unsigned char
。你太难了。“Convert to twos complete”是一种简单的转换为无符号类型的操作,可以覆盖整个范围;这会清理掉几行。“硬部分”是循环中的最后一位;它现在可以在这里的几个测试中使用。我将对最后一点进行分解,以便更清楚地说明发生了什么。进一步研究这个解决方案后,我认为这取决于
a
的大小是否大于
1
。否则面具会破。。。我想,如果这是个问题,你可以解决它。@R。。如果根据C标准,它确实是可移植的,那么这是非常有趣的。不过,我还不能完全理解这个道理。谢谢你和卡尔的帮助。只是想知道,有没有