Dlaczego ~a daje -6?

0

Witam!

Dlaczego wynik wyrażenia ~a to jest -6?

Na początku a to jest chyba 00000....101 , a po wykonaniu a=~a to 11111.......010 ale ta liczba nie pasuje mi do -6.

#include <iostream>

int main(void)
{
    int a=5;
    a=~a;
    std::cout << a;
    return 0;
}

Pozdrawiam

8

Słyszałeś o kodzie uzupełnień do dwójki? Jak nie, to poczytaj.

3

Znak liczby całkowitej jest przechowywany w najstarszym bicie. Aby dostać takie zachowanie jakiego oczekujesz musisz użyć typu liczby całkowitej bez znaku.

#include <iostream>

int main(void)
{
    unsigned int a=5;
    a=~a;
    std::cout << a;
    return 0;
}

5 w zapisie binarnym to 0b00000000000000000000000000000101
Wyświetla się 4294967290 czyli 0b11111111111111111111111111111010 - wszystko się zgadza.

0

To tylko połowicznie prawda, bo to co napisałeś bardziej pasuje do U1 niż do U2

1

Dzięki za pomoc

0

@hauleth: Ale jeśli rozważamy liczbę bez znaku to chyba nie ma sensu mówić o U1 i U2 bo to dla liczb ze znakiem jest

2
enedil napisał(a):

Słyszałeś o kodzie uzupełnień do dwójki? Jak nie, to poczytaj.

hauleth napisał(a):

To tylko połowicznie prawda, bo to co napisałeś bardziej pasuje do U1 niż do U2

W historii C standard kodowania liczb ze znakiem został (chyba) przyklepany relatywnie niedawno.

Za czasów jak sie uczyłem, było to otwarte, choć dominacja architektur rysowała się zdecydowanie.
Ale ciagle w instytutach stały mainframy (i były na chodzie) na których mogło być inaczej.
Ech były czasy, znak 6,7,8 albo 9 bitów ...

BTW
co by było gdyby jakiś kolega Johnego zakręcił korbką za bardzo
image
https://esensja.pl/obrazki/ilustracje/77964_9_aparacik_500.JPG

i wywłókł np emulatopr jakiejś Odry, IBMa360 itd jakby by tam sie C dziś zachowywał, wg wspólczesnych zasad czy tamtejszych ?

2
AnyKtokolwiek napisał(a):
enedil napisał(a):

Słyszałeś o kodzie uzupełnień do dwójki? Jak nie, to poczytaj.

hauleth napisał(a):

To tylko połowicznie prawda, bo to co napisałeś bardziej pasuje do U1 niż do U2

W historii C standard kodowania liczb ze znakiem został (chyba) przyklepany relatywnie niedawno.

Pierwotnie standard nie mówił jak mają być zakodowane liczby ujemne. Było chyba "implementation specified"
Chodziło o to, by pokryć dostępny hardware.
W czasach jak C zaczynało, procesory używany zarówno U1 i U2. U2 oczywiście wygrało, ale nadal było dużo legacy haradware (w przemyśle nie wymienia się komputerów często).
Dopiero jak uznano, że już mało kto tworzy oprogramowanie na procesory z U1 ustalono, w standardach C i C++, że ma być używane U2.

Przykładowo dopiero C++20 wprowadziło U2:
C++20 - cppreference.com

  • Signed integers are 2's complement
0

@MarekR22:

Całkiem umarł U1, czy się przemycił na jakiś małych gówienkach, albo na dedykach multicore 128b do grafiki ?

0
AnyKtokolwiek napisał(a):

@MarekR22:

Całkiem umarł U1, czy się przemycił na jakiś małych gówienkach, albo na dedykach multicore 128b do grafiki ?

Nikt od dawna nie robi hardware z U1. U2 ma same zalety (nie potrzeba specjalnych obwodów dla liczb ze znakiem, nie ma podwójnego zera). Standard trzymał możliwość obsługi U1 ponieważ jest dużo starego długożyciowego hardware. Przykładowo Odra służyła w PKP do 2010 roku.

5

W kodowaniu U2, żeby zanegować liczbę (zmienić jej znak) trzeba zanegować wszystkie bity i dodać 1 (to działa tak samo w obie strony, z + na − i z − na +, zawsze dodajemy 1).

Można powiedzieć że zachodzi równość -x == ~x + 1.

Zanegowałeś bity ale nie dodałeś 1, czyli otrzymałeś liczbę o 1 mniejszą (−6 zamiast −5).

1 użytkowników online, w tym zalogowanych: 0, gości: 1