Mam napisać program który wybiera bit z ciągu i wypisuje jego wartość, liczy ilość bitów, zamienia miejscami itp. (program ma być w c)
Problem polega na tym że nie wiem nawet od czego zacząć. Jak wytłumaczyć kompilatorowi żeby liczył od końca i żeby wiedział że liczba jest zapisana w systemie dwójkowym. Nie mogę też znaleźć nic podobnego w internecie ani w książce. Czy ktoś może pomóc?
Przepisz może polecenie, bo to co piszesz zbytnio się kupy nie trzyma. Komputery trzymają dane dwójkowo i nic nie musisz robić aby tak się działo.
Może inaczej, co jest na wejściu programu/zadania, co ma byc na wyjściu?
bool get_bit(unsigned int number, off_t bit) {
return (number & (1 << bit)) > 0;
}
unsigned int ones_count(unsigned int number) {
unsigned int result = 0;
while(number > 0){
if(number & 1) result++;
number <<= 1;
}
return result;
}
unsigned int swap_bits(unsigned int number, off_t bit_a, off_t bit_b) {
bool aval = get_bit(number, bit_a), bval = get_bit(number, bit_b);
if(aval == bval)
return number;
else
return (number ^ (1 << bit_a)) ^ (1 << bit_b);
}
komputer zawsze liczy w dwójkowym, tylko w ciągu znaków może być zapisane inaczej. Wczytujemy przeważnie za pomocą scanf
, fscanf
i sscanf
, w zależności od potrzeb. Dla systemu dziesiętnego używamy %d(liczba ze znakiem) i %u(liczba bez znaku), a dla szesnastkowego %x. Nie pytaj jak to działa, poczytaj o operatorach i popisz sobie programy testowe, to bardzo proste.
Ok. A jeśli mam przypadek że mam liczbę val=01001. Podaję numer bitu 3 i powinno mi zwrócić 1.
Jak mam to zapisać w c?
Moim problemem jest to, że nie rozumiem mechanizmu który jest tutaj użyty :/
jeśli wpiszesz w kodzie w C 01001
to jest to intepretowane jako 1001
zapisane w ósemkowym. W standardzie C chyba nie ma sposobu na podanie wartości binarnej. napisz 9 to dostaniesz to czego chcesz. Poza tym wedle kodu który podałem, numeracja zaczyna się od zera. Bit 0 to ten najbardziej po prawej (najmniej znaczący).
To na jakiej podstawie mam wybrać pozycję bitu?
int get_nth_bit(uint64_t value, int n)
{
return (value & (1 << n)) > 0;
}
Coś takiego.
A w zwykłym c?
A co jest takiego niezwykłego w tym co napisałem?
kq napisał(a):
A co jest takiego niezwykłego w tym co napisałem?
żeby mieć uint64_t
trzeba załączyć nagłówek stdint.h
, który jest częścią standardu C99. Naprzykład nie wiem czy kompilator z Redmond to obsłuży.. Człowiek pewnie uczy się na studia. Który nauczyciel akademicki wie że jest coś takiego jak C99? xD Tak w ogóle mało znam ludzi, którzy go znają.
To na jakiej podstawie mam wybrać pozycję bitu?
Co rozumiesz przez wybrać bit?
Może po prostu wyjaśnię, mamy 3 podstawowe operatory logiczne typu bitwise (tj. wykonujące tę samą operację na każdej parze bitów z dwóch zmiennych:
- AND(&) -- daje 1 jeśli oba bity wynoszą jeden. Ta operacja jest używana do zerowania bitów, względnie do maskowania.--
- OR(|) -- daje 1 jeśli jeden z bitów wynosi jeden. Ta operacja jest używana do ustawiania bitów.
- XOR(^) -- daje 1 jeśli tylko jeden z bitów wynosi jeden. Ta operacja jest używana do zmiany wartości bitów.
np.
1011b
& 0110b
------------
0010b // tylko bit #1 ma wartość jeden w obu liczbach
0001b
| 1001b
-----------
1001b // bity #0 i #3 mają wartość jeden w choć jednej z liczb
0100b
^ 1011b
-----------
1111b. // każda para bitów w liczbach ma inne wartości.
itd. Przypominam, że w C nie wpisuje się raczej binarnie, szesnastkowy jest najwygodniejszy, bo jedna cyfra odpowiada 4 cyfrom binarnym i jak się przyzwyczaisz z łatwością będziesz przekładał binarny na szesnastkowy, tak jest wygodniej.
Czasami używa się operacji przesunięcia bitowego żeby w czytalny sposób oznaczyć jeden bit, np. (1 << 6) oznacza bit 6 (numeracja od 0, bo przesuwamy jedynkę o 6 miejsc).
Naprawdę nie mogłeś tego sam znaleźć? Może po prostu się nie nadajesz?
C99 i C11, czyli po prostu C. Jak najbardziej zwykłego c.