C# ma różne typy wartości, a każda z nich służy ich własnym celom. Int32 mieści się w zakresie od - (0x7FFFFFFF + 1) do 0x7FFFFFFF iz każdej maszyny, w której kiedykolwiek go uruchomiłem, wydaje się, że niezaznaczone ((int) 0xFFFFFFFF) zawsze daje mi wynikową wartość -1. Czy tak jest zawsze? Ponadto .NET zawsze przedstawia -1 jako 0xFFFFFFFF w pamięci w dowolnym systemie? Czy bit wiodący zawsze jest bitem znaku? Czy zawsze używają one binarnej reprezentacji liczb całkowitych podpisywanych przez Uzupełnienie dla liczb całkowitych?Sposób w jaki C# reprezentuje ujemne liczby całkowite w pamięci i rzuca je niezaznaczone.
Odpowiedz
Dokumentacja dla System.Int32 wyraźnie stwierdza, że jest przechowywana w dwóch komplementach. Jest na samym dole:
Oprócz pracy z poszczególnych liczb jako wartości po przecinku, ty może chcieć wykonywać operacje bitowe z liczb całkowitych, lub pracować z binarnych lub szesnastkowym reprezentacji liczb całkowitych. Wartości Int32 są reprezentowane w 31 bitach, z trzydziestym drugim bitem używanym jako bit znaku. Wartości dodatnie są reprezentowane przez reprezentację znaku i wielkości w postaci . Wartości ujemne są reprezentowane przez dwa w dopełniaczach . Należy o tym pamiętać, wykonując operacje bitowe na wartościach Int32 lub pracując z pojedynczymi bitami . Aby wykonać operację numeryczną, logiczną lub porównawczą na dowolnych dwóch wartościach innych niż dziesiętne, obie wartości muszą używać tej samej reprezentacji .
Wygląda na to, że odpowiedź na wszystkie pytania brzmi "tak".
Również zakres dla Int32 wynosi od - (0x80000000) do 0x7FFFFFFFF.
C# - tak samo jak prawie każda inna "puter na planecie" - oznacza liczby całkowite w notacji uzupełnienia dwójki. Sądzę, że w tym czy innym punkcie zostały zaprojektowane procesory, które używały innej reprezentacji, ale w dzisiejszych czasach można całkiem niezawodnie polegać na liczbach całkowitych reprezentowanych w notacji uzupełniającej 2-go.
liczymy bitów od prawej do lewej strony, ze skrajnej prawej bit, bit 0 jest najmniej znaczący bit i skrajną lewą bit jest najbardziej istotne.
Bit wyższego rzędu (lewy) jest znakiem: 0 jest dodatnie; 1 jest ujemne.
Pozostałe bity przenoszą wartość. Oznacza to, że ważna domena liczby całkowitej N bitów to - (2 n-1) < = x < = + (2 n-1 -1). Co oznacza, że może być reprezentowana jedna dodatkowa liczba ujemna, niż liczba dodatnia: dla 16-bitowej liczby całkowitej ze znakiem, domena wynosi -32 768 do +32,767.
Aby umieścić numer na uzupełnienie dwójkowe jest proste:
- przekształcenia jej wartość bezwzględną do binarnego/base-2 notacji.
- gdy jest ujemna,
- inwertowany bity
- dodać 1
więc wartość +1 jest reprezentowane 0x0001, a -1 reprezentowane
- 0x0001 (wartość bezwzględna 1 w pliku binarnym)
- 0xFFFE (bity odwrócone)
- 0xFFFF (dodatek 1)
Albo 0xFFFF
Powodem zapisie dwójki dopełniacza jest to, że sprawia, że konstrukcja CPU prościej: ponieważ odejmowanie jest dodanie ujemnego (np 3-2 jest takie same jak 3 + -2), nie ma potrzeby projektowania obwodów odejmowania:
1-1 jest takie same jak 1 + 1 i ma wartość zero.
lub w hex,
0x0001 (decimal +1) + 0xFFFF (decimal -1) ====== 0x0000 (decimal 0)
Na większości procesorów, carry do lub z bitem wyższego rzędu wyznacza stały punkt przepełnienia flagę.
Bit wyższego rzędu nie jest "znakiem", który byłby reprezentacją "znaku + magnitudo". W uzupełnieniu do dwóch, bit wyższego rzędu ma ujemną wartość miejsca (dokładnie -2 razy wartość następnego bitu, więc jest to moc -2) –