4,4 — Liczby całkowite ze znakiem

An liczba całkowita jest typem całkowitym, który może reprezentować dodatnie i ujemne liczby całkowite, w tym 0 (np. -2, -1, 0, 1, 2). C++ ma 4 podstawowe podstawowe typy całkowite dostępne do użycia:

TypMinimum RozmiarUwaga
short int16 bitów
int16 bitówZwykle 32 bity w nowoczesnych architekturach
long int32 bity
długi długi wew64 bity

Kluczowa różnica między różnymi typami liczb całkowitych polega na tym, że mają one różne rozmiary — większe liczby całkowite mogą przechowywać większe liczby.

Przypomnienie

C++ gwarantuje jedynie, że liczby całkowite będą miały określony minimalny rozmiar, a nie, że będą miały określony rozmiar. Zobacz lekcję 4.3 -- Rozmiary obiektów i operator sizeof aby uzyskać informacje na temat określania wielkości każdego typu na komputerze.

Na marginesie…

Technicznie rzecz biorąc, bool i char typy są uważane za typy całkowite (ponieważ typy te przechowują swoje wartości jako wartości całkowite). Na potrzeby następnych kilku lekcji wykluczymy te typy z naszej dyskusji.

Liczby całkowite ze znakiem

Pisząc liczby ujemne w życiu codziennym, używamy znaku ujemnego. Na przykład, -3 oznacza „ujemne 3”. Zwykle też rozpoznajemy +3 jako „dodatnia 3” (chociaż powszechna konwencja nakazuje, aby zazwyczaj pomijać przedrostki plus).

Ten atrybut bycia dodatnim, ujemnym lub zerowym nazywany jest liczbą podpisać.

Domyślnie liczbami całkowitymi w C++ są podpisany, co oznacza, że ​​znak liczby jest przechowywany jako część wartości. Dlatego liczba całkowita ze znakiem może zawierać zarówno liczby dodatnie, jak i ujemne (oraz 0).

W tej lekcji skupimy się na liczbach całkowitych ze znakiem. Liczby całkowite bez znaku (które mogą zawierać tylko liczby nieujemne) omówimy w następnej lekcji.

Definiowanie liczb całkowitych ze znakiem

Oto preferowany sposób definiowania czterech typów liczb całkowitych ze znakiem:

short s;      // prefer "short" instead of "short int"
int i;
long l;       // prefer "long" instead of "long int"
long long ll; // prefer "long long" instead of "long long int"

Chociaż short int, long int lub długi długi wew będzie działać, wolimy krótkie nazwy dla tych typów (które nie używają rozszerzenia int przyrostek). Oprócz częstszego pisania, dodanie pliku int sufiks sprawia, że ​​typ jest trudniejszy do odróżnienia od zmiennych typu int. Może to prowadzić do błędów, jeśli przypadkowo pominiesz krótki lub długi modyfikator.

Typy całkowite mogą również przyjmować opcję opcjonalną podpisany słowo kluczowe, które zgodnie z konwencją jest zwykle umieszczane przed nazwą typu:

signed short ss;
signed int si;
signed long sl;
signed long long sll;

Jednak tego słowa kluczowego nie należy używać, ponieważ jest ono zbędne, ponieważ liczby całkowite są domyślnie podpisane.

Najlepsza praktyka

Preferuj typy skrócone, które nie używają int przyrostek lub signed prefiksu.

Zakresy liczb całkowitych ze znakiem

Jak dowiedziałeś się z ostatniej sekcji, zmienna with n bity mogą pomieścić 2n możliwe wartości. Ale jakie konkretne wartości? Nazywamy zbiorem określonych wartości, jakie może przechowywać typ danych zakresem. Zakres zmiennej całkowitej jest określony przez dwa czynniki: jej rozmiar (w bitach) oraz to, czy jest ona ze znakiem, czy nie.

Na przykład 8-bitowa liczba całkowita ze znakiem ma zakres od -128 do 127. Oznacza to, że 8-bitowa liczba całkowita ze znakiem może bezpiecznie przechowywać dowolną wartość całkowitą z zakresu od -128 do 127 (włącznie).

Oto tabela zawierająca zakres liczb całkowitych ze znakiem o różnych rozmiarach:

Rozmiar/typZakres
Podpisany 8-bitowo-128 do 127
16-bitowy podpisany-32 768 do 32 767
Podpisany 32-bitowy-2 147 483 648 do 2 147 483 647
Podpisany 64-bitowy-9 223 372 036 854 775 808 do 9 223 372 036 854 775 807

W przypadku matematyki n-bitowa zmienna ze znakiem ma zakres -(2n-1) do (2n-1)-1.

Dla osób, które nie mają skłonności do matematyki… skorzystaj z tabeli. :)

Dla zaawansowanych czytelników

Powyższe zakresy zakładają reprezentację binarną „dopełnienia do dwóch”. Ta reprezentacja jest de facto standardem dla nowoczesnych architektur (ponieważ jest łatwiejsza do wdrożenia na sprzęcie) i jest obecnie wymagana przez standard C++ 20. Na lekcji omawiamy uzupełnienie do dwójki O.4 -- Konwersja liczb całkowitych pomiędzy reprezentacją binarną i dziesiętną.

We wcześniejszych standardach reprezentacje wielkości znaku i uzupełnienia były dozwolone ze względów historycznych. Takie reprezentacje dają wartości w zakresie -(2n-1-1) do +(2n-1-1).

Przepełnienie

Co się stanie, jeśli spróbujemy przypisać wartość 140 do 8-bitowej liczby całkowitej ze znakiem? Ta liczba jest poza zakresem, jaki może pomieścić 8-bitowa liczba całkowita ze znakiem. Liczba 140 wymaga 9 bitów do reprezentacji (8 bitów wielkości i 1 bit znaku), ale mamy tylko 8 bitów (7 bitów wielkości i 1 bit znaku) dostępnych w 8-bitowej liczbie całkowitej ze znakiem.

Standard C++20 podaje ogólne stwierdzenie: „Jeśli podczas oceny wyrażenia wynik nie jest zdefiniowany matematycznie lub nie mieści się w zakresie możliwych do przedstawienia wartości dla jego typu, zachowanie jest niezdefiniowane”. Potocznie nazywa się to przepełnieniem.

Dlatego przypisanie wartości 140 do 8-bitowej liczby całkowitej ze znakiem spowoduje niezdefiniowane zachowanie.

Jeśli operacja arytmetyczna (taka jak dodawanie lub mnożenie) próbuje utworzyć wartość spoza zakresu, który można przedstawić, nazywa się to liczbą całkowitą przepełnienie (lub przepełnienie arytmetyczne). W przypadku liczb całkowitych ze znakiem przepełnienie liczb całkowitych spowoduje niezdefiniowane zachowanie.

#include <iostream>

int main()
{
    // assume 4 byte integers
    int x { 2'147'483'647 }; // the maximum value of a 4-byte signed integer
    std::cout << x << '\n';

    x = x + 1; // integer overflow, undefined behavior
    std::cout << x << '\n';

    return 0;
}

Na komputerze autora wydrukowano powyższy komunikat:

2147483647
-2147483648

Ponieważ jednak drugie wyjście jest wynikiem niezdefiniowanego zachowania, wartość wyjściowa może się różnić na Twojej maszynie.

Dla zaawansowanych czytelników

Omawiamy, co się dzieje, gdy na lekcji przepełnią się liczby całkowite bez znaku 4.5 -- Liczby całkowite bez znaku i dlaczego ich unikać.

Ogólnie rzecz biorąc, przepełnienie powoduje utratę informacji, co prawie nigdy nie jest pożądane. Jeśli istnieje dowolnego podejrzenie, że obiekt może potrzebować przechowywać wartość spoza jego zakresu, użyj typu o większym zakresie!

Dzielenie na liczbach całkowitych

Podczas dzielenia dwóch liczb całkowitych C++ działa tak, jak można się spodziewać, gdy iloraz jest liczbą całkowitą:

#include <iostream>

int main()
{
    std::cout << 20 / 4 << '\n';
    return 0;
}

Daje to oczekiwany wynik:

5

Ale spójrzmy, co się dzieje, gdy dzielenie liczb całkowitych powoduje wynik ułamkowy:

#include <iostream>

int main()
{
    std::cout << 8 / 5 << '\n';
    return 0;
}

To daje prawdopodobnie nieoczekiwane wynik:

1

Podczas dzielenia dwóch liczb całkowitych (tzw. dzielenie przez liczby całkowite) C++ zawsze daje wynik w postaci liczby całkowitej. Ponieważ liczby całkowite nie mogą przechowywać wartości ułamkowych, każda część ułamkowa jest po prostu pomijana (a nie zaokrąglana!).

Przyglądając się bliżej powyższemu przykładowi, 8 / 5 daje wartość 1,6. Część ułamkowa (0,6) jest odrzucana, a wynik 1 pozostaje. Alternatywnie możemy powiedzieć, że 8 / 5 równa się 1 reszcie 3. Pozostałość jest odrzucana, pozostawiając 1.

Podobnie, -8 / 5 daje wartość -1.

Ostrzeżenie

Bądź ostrożny podczas dzielenia liczb całkowitych, ponieważ stracisz części ułamkowe ilorazu. Jeśli jednak tego chcesz, dzielenie liczb całkowitych jest bezpieczne, ponieważ wyniki są przewidywalne.

Jeśli pożądane są wyniki ułamkowe, na lekcji pokażemy, jak to zrobić. 6.2 — Operatory arytmetyczne.

Czas quizu

Pytanie nr 1

Jaki byłby zakres 5-bitowej liczby całkowitej ze znakiem?

Pokaż rozwiązanie

Pytanie nr 2

a) Jaki jest wynik 13 / 5?

Pokaż rozwiązanie

b) Jaki jest wynik -13 / 5?

Pokaż rozwiązanie

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
431 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze