簡體   English   中英

有符號整數和無符號整數有什么區別

[英]What is the difference between signed and unsigned int

有符號整數和無符號整數有什么區別?

您可能知道, int以二進制形式在內部存儲。 通常int包含 32 位,但在某些環境中可能包含 16 或 64 位(甚至是不同的數字,通常但不一定是 2 的冪)。

但是對於這個例子,讓我們看看 4 位整數。 很小,但對於說明目的很有用。

由於這樣的整數有 4 位,因此它可以采用 16 個值之一; 16 是 2 的四次方,或 2 乘以 2 乘以 2。這些值是多少? 答案取決於這個整數是有signed int還是unsigned int 對於unsigned int ,該值永遠不會為負; 沒有與該值相關聯的符號。 以下是四位unsigned int的 16 個可能值:

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000    8
1001    9
1010   10
1011   11
1100   12
1101   13
1110   14
1111   15

...這里是四位有signed int的 16 個可能值:

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000   -8
1001   -7
1010   -6
1011   -5
1100   -4
1101   -3
1110   -2
1111   -1

如您所見,對於有signed int s,當且僅當數字為負時,最高有效位為1 這就是為什么,對於有signed int s,這個位被稱為“符號位”。

用外行的話來說,unsigned int 是一個不能為負的整數,因此它可以假設的正值范圍更大。 有符號 int 是一個整數,它可以是負數,但具有較低的正范圍以換取它可以假設的更多負值。

intunsigned int是兩種不同的整數類型。 int也可以稱為signed int ,或者只是signedunsigned int也可以稱為unsigned 。)

顧名思義, int是有符號整數類型,而unsigned int無符號整數類型。 這意味着int能夠表示負值,而unsigned int只能表示非負值。

C 語言對這些類型的范圍提出了一些要求。 int的范圍必須至少為-32767 .. +32767 ,而unsigned int的范圍必須至少為0 .. 65535 這意味着兩種類型都必須至少為 16 位。 它們在許多系統上是 32 位,在某些系統上甚至是 64 位。 由於大多數現代系統使用二進制補碼表示, int通常具有額外的負值。

也許最重要的區別是有符號和無符號算術的行為。 對於 signed int ,溢出具有未定義的行為。 對於unsigned int ,沒有溢出; 任何產生超出類型范圍的值的操作都會環繞,例如UINT_MAX + 1U == 0U

任何整數類型,無論是有符號還是無符號,都對無限數學整數集的子范圍進行建模。 只要您使用類型范圍內的值,一切都會正常。 當您接近類型的下限或上限時,您會遇到不連續性,並且可能會得到意想不到的結果。 對於有符號整數類型,僅當非常大的負值和正值超過INT_MININT_MAX 對於無符號整數類型,非常大的正值和零會出現問題。 這可能是錯誤的來源。 例如,這是一個無限循環:

for (unsigned int i = 10; i >= 0; i --) [
    printf("%u\n", i);
}

因為i總是大於或等於零; 這就是無符號類型的本質。 (在循環內部,當i為零時, i--將其值設置為UINT_MAX 。)

有時我們事先知道存儲在給定整數變量中的值總是正的——例如,當它僅用於計數時。 在這種情況下,我們可以將變量聲明為無符號變量,例如unsigned int num student; . 使用這樣的聲明,允許的整數值范圍(對於 32 位編譯器)將從 -2147483648 到 +2147483647 的范圍轉移到 0 到 4294967295 的范圍。因此,將整數聲明為無符號幾乎會使最大可能的大小增加一倍否則它可以持有的價值。

在實踐中,有兩個區別:

  1. 打印(例如 C++ 中的coutprintf中的printf ):無符號整數位表示被打印函數解釋為非負整數。
  2. ordering :排序取決於簽名或未簽名的規范。

此代碼可以使用排序標准識別整數:

char a = 0;
a--;
if (0 < a)
    printf("unsigned");
else
    printf("signed");

char被認為是signed一些編譯器和unsigned在其他的編譯器。 上面的代碼使用排序標准確定在編譯器中考慮哪一個。 如果a是無符號的,在a--之后,它將大於0 ,但如果它是有signed ,它將小於零。 但在這兩種情況下,該位表示a是相同的。 也就是說,在這兩種情況下, a--對位表示進行相同的更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM