简体   繁体   English

将32位大字节序有符号整数转换为有符号小字节序整数

[英]convert 32 bit big endian signed integer to signed little endian integer

I had some unsigned 32 bit big-endian integers that I needed to convert, and that was trivially easy once I found the right header: 我有一些需要转换的无符号32位大端整数,一旦找到正确的标头,这将非常容易:

#include <endian.h>
...
be32toh(some_int);

However, endian.h specifies these are for unsigned integers. 但是, endian.h指定这些用于无符号整数。 For a signed integer, I'm not really sure what to do, as it doesn't look like there are header files for this sort of thing, and I'm not really familiar with bit manipulation in C++. 对于带符号的整数,我不太确定该怎么做,因为它看起来好像没有用于此类操作的头文件,而且我对C ++中的位操作并不十分熟悉。

Edit: Since there is some confusion about the format of my integer, let me explain more. 编辑:由于我的整数格式有些混乱,让我解释更多。 I have an integer in the form 我有一个整数形式

abcdefghijklmnopqrstuvwxyz012345

where each character represents a bit. 每个字符代表一点。 the a bit represents the sign. a位代表符号。 I know that bytes are always big endian, so in addition to moving the bytes into a different order, like 我知道字节始终是大端字节,因此除了将字节移动到其他顺序之外,例如

yz012345qrstwx...

I also need some way to make sure that the y bit shows the sign, not just some bit in the number. 我还需要某种方法来确保y位显示符号,而不仅仅是数字中的一点。 I ... have no idea how to do that. 我...不知道该怎么做。

Edit: my problem was that I was thinking that the sign bit was always first in order, when that is not the case. 编辑:我的问题是我一直在考虑符号位总是按顺序排在第一位,而事实并非如此。 The sign bit is always the MSB, meaning that if you're in little-endian form, the sign bit is going to be in the middle of the bytes that make up your integer. 符号位始终是MSB,这意味着如果您采用小尾数形式,则符号位将位于组成整数的字节的中间。

Trying to byte-reverse a signed integer doesn't sound like it's a well-defined arithmetic operation, because the most significant bit behaves as an indicator of the sign of the integer, and it wouldn't make much sense to move that elsewhere when manipulating an integer variable. 尝试对有符号整数进行字节反转听起来并不像是定义良好的算术运算,因为最高有效位的作用是指示该整数的符号,并且当将其移至其他位置时没有多大意义操作整数变量。

More likely, you may have sequence of 4 bytes that represent a 32-bit signed integer, but need to be byte-reversed in order to translate between different CPU endiannesses. 更有可能的是,您可能有4个字节的序列,这些序列表示一个32位带符号整数,但是需要进行字节反转才能在不同的CPU字节序之间进行转换。 To do that, you can simply treat the quantities as though they were unsigned, and let be32toh() do the work for you: 为此,您可以简单地将数量视为未签名的数量,然后让be32toh()为您完成工作:

(int)be32toh((unsigned)some_int);

or, slightly safer: 或者,稍微安全一些:

(int32_t)be32toh((uint32_t)some_int);

This works because the casting operations, when applied to integers of the same bit-depth, effectively leaves the in-memory representations unchanged. 之所以可行,是因为当将转换操作应用于相同位深度的整数时,有效地保留了内存中的表示形式。 This ignores the significance of the sign (and any subtleties related to the twos-complement representation of signed integers) while doing the byte-reversal. 在进行字节反转时,这忽略了符号的重要性(以及与带符号整数的二进制补码表示有关的任何细微差别)。 I'm not sure that this behaviour is guaranteed by the C standard (a question for language lawyers, perhaps), but it's likely to be a very common behaviour. 我不确定这种行为是否受到C标准的保证(也许是语言律师的问题),但这很可能是一种非常常见的行为。 The description at www.cplusplus.com indicates that provided your system uses twos-complement representation for its signed integers (which is very common) then the signed-to-unsigned conversion in (uint32_t)some_int will do the right thing. www.cplusplus.com上的描述表明,只要您的系统对其有符号整数使用二进制补码表示(这是很常见的),则(uint32_t)some_int的有符号到无符号转换将做正确的事情。 However, the precise interpretation of the signed-to-unsigned conversion in (int32_t)be32toh(...) is, strictly, implementation dependent. 但是,严格来说,对(int32_t)be32toh(...)有符号到无符号转换的精确解释是依赖于实现的。 So, again, I think the question of what it would mean to byte-reverse a signed integer isn't mathematically unambiguous. 因此,我再次认为,字节反转有符号整数的含义在数学上不是明确的。

This only makes sense if the native system is little endian, because what would be the point of converting data to signed little-endian on a big-endian system? 仅当本机系统为Little Endian时才有意义,因为在big-endian系统上将数据转换为带符号的Little-endian的意义何在?

So on a little-endian system, all you need to do is cast the big-endian integer to unsigned, convert it using be32toh , and then cast the result to signed integer. 因此,在little-endian系统上,您所需要做的就是将big-endian整数转换为unsigned,使用be32toh对其进行be32toh ,然后将结果转换为有符号整数。 Actually, it's better to represent the big-endian as unsigned from the start, because its sign has no meaning in a little-endian system. 实际上,最好从一开始就将big-endian表示为无符号,因为它的符号在little-endian系统中没有任何意义。 So, just convert the unsigned bits, and then cast to signed. 因此,只需转换无符号位,然后转换为有符号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM