2010-02-11 203 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

相關問題