有一个文章,解释了小/大端主题,它包含了一个endianness转换函数的示例:
short reverseShort (short s) {
unsigned char c1, c2;
if (is_bigendian()) {
return s;
} else {
c1 = s & 255;
c2 = (s >> 8) & 255;
return (c1 << 8) + c2;
}
}我明白,为什么他们-在这里:
c1 = s & 255;255 = 11111111 (按位排列)和s (可能类似于1011011010010010 )不会影响最后8个位置中的数字,而是将所有的领先位置变为零。所以它是切位到8结尾。
我也明白,为什么他们在这里使用右移:
c2 = (s >> 8) & 255;最后8位移动8位,所以领先8位。所以在第一次操作中,他们得到最后的8位,然后是前8位。
但为什么他们又要用255“和”呢?
发布于 2015-08-28 18:49:39
让我们假设s= binary representation: abcdefghijklmnopqrst
c1 = s & 255; // < mnopqrst first 8 bits
c2 = (s >> 8) & 255; // from abcdefghijklmnopqrst >> 8 = abcdefghijkl & b11111111 = efghijkl
return (c1 << 8) + c2; // < (mnopqrst00000000) + efghijkl = mnopqrstefghijkl从本质上说,它取前8位和下8位,然后反转它们。
但他们为什么要再用255块呢?
如果它的长度更长,那就把它截断为8位。
发布于 2015-08-29 03:56:39
问题的根源在于s是一个签署的短消息。如果s有一个负值,那么s >> 8会导致实现定义的行为。
通常,实现定义,在这种情况下,从左边移进来的位会被1填充。因此,在这些实现上,10000000 00000000将8移到右边的结果将是11111111 10000000。现在,应用& 255将将其转化为00000000 10000000,这是所需的结果。
正如注释中所指出的,(假设8位字符和2的补码算法)转换为unsigned char具有与& 255相同的效果。由于结果存储在unsigned char中,因此在这些假设下,& 255是多余的。
另一种不依赖于实现定义的行为来编写代码的方法是:
(unsigned short)s >> 8当右移时,无符号类型总是用零填充.
一个更好的方法是,如果函数同时接受并返回unsigned short。就目前情况而言,如果返回的值大于SHRT_MAX,则return (c1 << 8) + 2将导致未定义或实现定义的行为。
https://stackoverflow.com/questions/32277760
复制相似问题