İşaretli ve işaretsiz int arasındaki fark nedir


91

İşaretli ve işaretsiz int arasındaki fark nedir?


5
Bu gerçek bir sorudur ve cevap o kadar basit değil, oldukça ince.
R .. GitHub BUZA YARDIM ETMEYİ DURDUR

Yeniden açılması için oylama. Kopya olabilir, ama kesinlikle gerçek bir soru.
Brian


Birçok dilde kullanıldığından daha fazla etiket eklenmelidir.
Juan Boero

Bu sorunun detaylandırılması için bir bölüme ihtiyacı olabilir. Girişleri ve çıkışları bilmek istiyorsanız, daha fazla açıklama için İmzasız ve İmzalı Tam Sayılar'ı kontrol edin .
anonim

Yanıtlar:


113

Muhtemelen bildiğiniz gibi, inte'ler dahili olarak ikili olarak saklanır. Tipik olarak bir int32 bit içerir, ancak bazı ortamlarda 16 veya 64 bit (veya hatta farklı bir sayı, genellikle ancak ikinin kuvveti olması gerekmez) içerebilir.

Ancak bu örnek için 4 bitlik tam sayılara bakalım. Küçük, ancak açıklama amacıyla kullanışlıdır.

Böyle bir tamsayıda dört bit olduğundan, 16 değerden birini alabilir; 16'nın ikiye dördüncü kuvveti veya 2 çarpı 2 çarpı 2 çarpı 2. Bu değerler nelerdir? Cevap, bu tam sayının a signed intveya a olmasına bağlıdır unsigned int. Bir ile unsigned intdeğer hiçbir zaman negatif değildir; değerle ilişkili bir işaret yok. İşte dört bitin 16 olası değeri unsigned int:

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

... ve İşte dört bitin 16 olası değeri signed int:

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

Gördüğünüz gibi, signed ints için en önemli bit, 1ancak ve ancak sayı negatifse. Bu nedenle, signed ints için bu bit "işaret biti" olarak bilinir.


11
Belki de belirtmeye değer, bu ikisinin tamamlayıcı formatıdır ve kuşkusuz bugünlerde yaygın olarak kullanılmaktadır. İşaretli tam sayıları temsil etmenin başka yolları da vardır, en önemlisi kişinin tamamlayıcısı.
Planlayıcı

Doğru. Ve ISO9899 C standardı, birinin tamamlayıcısının veya ikisinin tümleyicisinin kullanılmasını bile gerektirmez; gerçekten işe yarayan diğer herhangi bir sözleşmeye izin verilebilir.
Bill Evans, Mariposa'da

1
İkinin tamamlayıcısı gerekli olmasa da, 2'nin tamamlayıcısı için önemsiz bir şekilde doğru olan ancak diğer temsiller (unsigned)(-1)için geçerli olmayan unsigned(ikili gösterimden bağımsız) maksimum temsil edilebilir değer olması gerekir .
rubenvb

3
@BillEvansatMariposa: Standart, işaretli tamsayılar için izin verilen 3 temsil olduğunu söylüyor: işaret + büyüklük, 2'nin tamamlayıcısı, 1'in tümleyicisi. Diğer herhangi biri program tarafından görünmez olmalı ve bunlardan biri olarak algılanmalıdır. 3
Alexey Frunze

Tamam ama kaputun altında! GERÇEKTEN neler oluyor! İMZALANMIŞ ve İMZALANMAMIŞ numara arasındaki fark nedir! Makine hesaplamayı nasıl yönetiyor? Sadece diğerinden bir değer mi çıkarıyor? 1111 = 15 ve 1111 = -1'i nasıl fark eder?
Mihail Georgescu

19

intve unsigned intiki farklı tam sayı türüdür. ( intaynı zamanda signed intveya sadece olarak da ifade edilebilir signed; unsigned intolarak da ifade edilebilir unsigned.)

İsimleri ima olarak, intbir olduğunu imzalı tamsayı türü ve unsigned intbir olan işaretsiz tamsayı türü. Bu int, negatif değerleri temsil edebileceği ve unsigned intyalnızca negatif olmayan değerleri temsil edebileceği anlamına gelir .

C dili, bu türlerin aralıklarına bazı gereksinimler getirir. Aralığı inten az -32767.. olmalı +32767ve aralığı unsigned inten az 0.. olmalıdır 65535. Bu, her iki türün de en az 16 bit olması gerektiği anlamına gelir. Birçok sistemde 32 bit, hatta bazılarında 64 bittir. intÇoğu modern sistem tarafından kullanılan ikinin tamamlayıcı gösterimi nedeniyle genellikle ekstra bir negatif değere sahiptir.

Belki de en önemli fark, işaretli ve işaretsiz aritmetiğin davranışıdır. İmzalandığında int, taşma tanımsız davranışa sahiptir. Çünkü unsigned inttaşma yok; örneğin, türün aralığı dışında bir değer veren herhangi bir işlem etrafını sarar UINT_MAX + 1U == 0U.

İşaretli veya işaretsiz herhangi bir tam sayı türü, matematiksel tam sayıların sonsuz kümesinin bir alt aralığını modeller. Bir tür aralığındaki değerlerle çalıştığınız sürece, her şey çalışır. Bir türün alt veya üst sınırına yaklaştığınızda, bir süreksizlikle karşılaşırsınız ve beklenmedik sonuçlar elde edebilirsiniz. İşaretli tam sayı türleri için, sorunlar yalnızca çok büyük negatif ve pozitif değerler için ortaya çıkar, INT_MINve INT_MAX. İşaretsiz tamsayı türleri için, çok büyük pozitif değerler için ve sıfırda sorunlar oluşur . Bu bir hata kaynağı olabilir. Örneğin, bu sonsuz bir döngüdür:

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

çünkü iher zaman sıfırdan büyük veya sıfıra eşittir; imzasız türlerin doğası budur. (Döngünün içinde isıfır olduğunda i--değerini olarak ayarlar UINT_MAX.)


12

Bazen, belirli bir tamsayı değişkeninde depolanan değerin her zaman pozitif olacağını önceden biliyoruz - örneğin, yalnızca şeyleri saymak için kullanıldığında. Böyle bir durumda değişkeni, 'de olduğu gibi işaretsiz olarak ilan edebiliriz unsigned int num student;. Böyle bir bildirimle, izin verilen tam sayı değerleri aralığı (32 bitlik bir derleyici için) -2147483648 ila +2147483647 aralığından 0 ila 4294967295 aralığına kayacaktır. Bu nedenle, bir tamsayıyı işaretsiz olarak bildirmek, mümkün olan en büyük boyutun neredeyse iki katına çıkar. aksi takdirde tutabileceği değer.


@Alex 10 dakika önce bu cevabı düzenlemenin ortasındaydım ve bu aynı. lol
Skuld

12

Laymen'in terimleriyle, işaretsiz bir tamsayı, negatif olamayan ve bu nedenle alabileceği daha yüksek bir pozitif değerler aralığına sahip bir tam sayıdır. İşaretli bir tamsayı, negatif olabilen, ancak alabileceği daha negatif değerler karşılığında daha düşük bir pozitif aralığa sahip olan bir tamsayıdır.


0

Pratikte iki fark vardır:

  1. yazdırma (örneğin cout, C ++ veya printfC ile): işaretsiz tamsayı bit gösterimi, yazdırma işlevleri tarafından negatif olmayan bir tam sayı olarak yorumlanır.
  2. sıralama : sipariş, imzalı veya işaretsiz özelliklere bağlıdır.

bu kod, tamsayıyı sıralama kriterini kullanarak tanımlayabilir:

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

Bu, biri negatif sayılarla, diğeri ile farklı olanı açıkladıysa, hayır. Bu gönderiye çok yardımcı olur.
Daniel Jackson

@DanielJackson Ne söylediğiniz net değil. derleyiciye bağlı olarak bir karakter negatif veya pozitif olarak kabul edilebilir. kodun çıktısı, derleyicinin seçtiği şeye bağlıdır ve bu, işaretli ve işaretsiz arasındaki farkı gösterir.
Minimus Heximus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.