2012-04-06 86 views
5

很簡單的問題傢伙,但也許我只是忘記了一些東西。 在64bit linux中,長度是8bytes是否正確? 。如果是這樣的話,我想設置的第64位,我可以做到以下幾點:長型64位linux

unsigned long num = 1<<63; 

每當我編這一點,但是,它給了我一個錯誤,說我左移超過寬度。 另外,如果我想需要很長型(無符號擴展)的第一個32位,我該怎麼辦:

num = num&0xFFFFFFFF; 

或怎麼樣:

num = (int)(num); 

謝謝。

+5

嘗試:'無符號長NUM = 1UL << 63;' – Mysticial 2012-04-06 06:48:37

+0

@Mysticial爲什麼不張貼與整數促進東西沿着一個答案? – cnicutar 2012-04-06 06:50:19

+1

取決於使用哪個編譯器。即使在64位機器上運行,許多遺留編譯器也會缺省爲32位。在再試一次之前確認'sizeof num'是8。 – wallyk 2012-04-06 06:51:04

回答

3

在64bit的linux中,長是8bytes是否正確?

不需要。取決於編譯器而不是基礎操作系統。仔細檢查一下這個討論。 What decides the sizeof an integer?

每當我編譯這一點,但是,它給了我一個錯誤,說我 向左移位超過寬度

每個人都已經回答了這一點。使用1UL

另外,如果我想利用類型的第一個32位(不 符號擴展),我可以這樣做:

num = num&0xFFFFFFFF; 
or what about: 

num = (int)(num); 

num = num&0xFFFFFFFF。這會給你更低的32位。但請注意,如果long僅在您的系統上有4個字節,那麼您將得到整個的。來到符號擴展部分,如果您使用了long而不是unsigned long,那麼您無法取消符號擴展位。例如,-1表示爲從第0位開始的全1。你將如何通過掩蔽來避免這些問題?

num = (int)(num)會給你低32位,但編譯器可能會通過溢出異常警告,如果num不適合的int

+0

同意C不會在64位機器上強制使用64位。但是,Linux隱含地強加這一點。只要看看通過'unsigned long'傳遞的所有指針和通過'signed long'傳遞的內存偏移量(例如系統調用)。因此,只要linux源代碼不會大幅改變,我會回答** yes **問題:「在64位linux中,」長「是8字節,是正確的?」 – 2017-01-13 09:14:17

0

我相信第一個問題的問題是編譯器將'1'視爲整數,而不是長整數。它不會在分配之後纔算出來。其實

unsigned long num = (unsigned long)1<<63; 
+0

你碰巧知道我的問題的第二部分的答案。關於獲取非符號擴展的前32位?我會做類似於num = num&(unsigned long)(0xFFFFFFFF)嗎? – de1337ed 2012-04-06 07:48:46

+0

@ de1337ed我已經回答了Qn的第二部分。檢出 – 2012-04-06 09:52:00

4

,如果你想爲你的整數部分精確長度(比特),假設C99符合標準的編譯,#include <stdint.h>和使用類型,如int64_tint32_t

您可以通過執行修復等一個方便的類型是intptr_t,整數類型具有相同數目的比特作爲void*指針(這樣就可以把它稱爲機器「字」)

+1

符合C99的編譯器不需要提供固定寬度的類型,例如'int64_t'。 *只需要提供8位,16位,32位和64位整數類型而無填充位的二進制補碼實現*需要*在'stdint.h'中提供固定寬度的整數類型定義。 – dreamlax 2012-04-06 07:29:15

1

對於便攜性可以使用:

limits.h中

#define LNG_BIT (sizeof(long) * CHAR_BIT) 

unsigned long num = 1UL << (LNG_BIT - 1); 

得到 「低INT」,有點像?:

#define INT_BIT (sizeof(int) * CHAR_BIT) 

if (LNG_BIT > INT_BIT) 
    return num & (~0UL >> INT_BIT); 
else 
    return num; 

num &= ~(~0U << INT_BIT); 

或者,使用面膜,等等取決於爲什麼,爲了什麼等你想要的int位。

另請注意編譯器提供的選項;即如果你正在使用gcc:

-m32
-m64
-mx32
       生成的代碼爲32位或64位環境。
        *的-m32選項集INT,長和指針類型爲32位,併產生任何I386系統上運行的代碼。
          * -m64選項將int設置爲32位,將長指針和指針類型設置爲64位,並生成x86-64體系結構的代碼。對於達爾文,只有-m64選項也會關閉-fno-pic和-mdynamic-no-pic選項。
          * -mx32選項將int,long和指針類型設置爲32位,並生成x86-64體系結構的代碼。

還有-maddress-mode=long

-maddress模式=長
       產生用於長地址模式的代碼。這僅適用於64位和x32環境。這是64位環境的默認地址模式。

0

AFAIR這樣的代碼在幾年前是reiserfs的一個重大錯誤的根源:

unsigned long num = 1<<63; 

如果您談論x86_64,是的,長64位,在大多數其他64位Linux平臺上。問題是代碼中的163都是簡單的int,所以結果未定義。更好地利用

unsigned long num = 1UL<<63; 

unsigned long num = (unsigned long)1<<63;