2010-02-11 197 views
8

可以说我有4Byte整数,我想将它转换为2Byte短整数。我是对的,在这两个(小端和大端)短整数将由2个4Byte整数的最低有效字节组成?Little endian与Big endian

第二个问题:
这样的代码在小端和大端处理器中的结果是什么?

int i = some_number; 
short s = *(short*)&i; 

恕我直言在大端处理器2最重要的字节将被复制,并在小尾数2最不重要的字节将被复制。

+0

我建议在复制之前使用数学将数量减少到适当的范围(大小)。编译器将保持Endianness,所以你不会有太多担心。复制部分变量会导致Endianness问题,如您所提出的。 – 2010-02-11 23:09:39

回答

12

我是对的,在这两个短整数将由2个4Byte整数的最低有效字节?

是的,根据定义。

bigE和littleE的区别在于最低有效字节是否在最低地址。在一个小端处理器上,最低位地址是最低位,x86是这样做的。

这些给予同样的结果在小E.

short s = (short)i; 
short s = *(short*)&i; 

在大端处理器,最高地址是最显著位,68000和Power PC做这种方式(实际上的Power PC既可以是从苹果公司,但PPC机器使用璧合)

这些给予同样的结果在大E.

short s = (short)i; 
short s = ((short*)&i)[1]; // (assuming i is 4 byte int) 

所以,你可以看到,小端可以让你获得里斯t操作数的有效位而不知道它有多大。小E有利于保持向后兼容性。

那么大端的优势是什么? 它创建更容易阅读的十六进制转储。

真的,摩托罗拉的工程师认为,减轻读取十六进制转储的负担比向后兼容性更重要。英特尔的工程师则相反。

+0

我不确定后向兼容性参数是否非常强大,因为程序错误地认为某些变量具有特定的大小会因为其他原因(即使是在小端机器上(例如,处理数组时))而更有可能中断。我认为它更多的是在编译器或硬件内部进行一些低级别的优化和其他技巧。 – 2010-02-11 21:58:13

+0

@Josef:是的,我确信硬件设计者为什么喜欢小E的原因很多,兼容性对他们来说可能不是那么重要。但事实证明,从80886移动到286/386时,它很重要。为8088编写的代码仍然可以在现代x86/x64处理器上运行。 – 2010-02-11 22:05:49

+0

是的,通过始终保留前几代的整个指令集,x86架构在二进制级别,设计(无论好坏)都是向后兼容的。无可否认,这与我的专业领域相接近,但在这方面没有多少endian帮助,除了可能为mov指令略微简化电路逻辑?对于不同的数据大小(字节,字,双字等),您仍然有不同的操作码。 – 2010-02-11 23:04:30

2
  1. 是的。当你转换值时,你不必担心排序。

  2. 是的。当你转换指针时,你会这样做。

+0

从本质上来说,唯一需要转换指针的重要方式就是串行化数据(即文件或网络I/O)。但是在那种情况下,你真的不必担心,因为读者可能会使用不同的字节顺序。 – 2010-02-11 23:58:42

1

首先,你可能已经知道了,但让我提,INT的大小并不保证为4个字节,并且在所有平台短,2个字节。

如果你的第一个问题,你的意思是这样:

int i = ...; 
short s = (short)i; 

然后是,s将包含i低字节(一个或多个)。

我认为你的第二个问题的答案也是肯定的;在字节级别,系统的字节顺序确实起作用。

1

你应该知道,你的第二个例子

int i = some_number; 
short s = *(short*)&i; 

不是因为它违反了严格别名规则有效的C代码。在某些优化级别和/或编译器下很可能会失败。

对于使用工会:

union { 
    int i; 
    short s; 
} my_union; 

my_union.i = some_number; 
printf("%d\n",my_union.s); 

此外,如别人注意,你不能假设你的整数为4个字节。当你需要特定的尺寸时,最好使用int32_t和int16_t。

+0

它如何违反严格的别名? – 2010-02-11 21:35:27

+1

向一位工会会员写信和从另一位工作人员读取的是UB。 – dalle 2010-02-11 21:47:43

+0

这不是锯齿违规。它只是颠覆了类型系统,它从来没有实际创建一个指针。 – 2010-02-11 22:00:38

1

如果你真的想要一个int转换为短,那么就这样做:

short int_to_short(int n) { 
    if (n < SHRT_MIN) return SHRT_MIN; 
    if (n > SHRT_MAX) return SHRT_MAX; 
    return (short)n; 
} 

你不必甚至担心端,语言处理,对你。如果你确定n在短期的范围内,那么你也可以跳过支票。

+0

我并不担心,我只是好奇结果会是什么。 – 2010-02-11 21:59:08

相关问题