operacje na bitach w c

0

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?

0

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.

1

Może inaczej, co jest na wejściu programu/zadania, co ma byc na wyjściu?

0
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.

0

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 :/

1

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).

0

To na jakiej podstawie mam wybrać pozycję bitu?

1
int get_nth_bit(uint64_t value, int n)
{
    return (value & (1 << n)) > 0;
}

Coś takiego.

0

A w zwykłym c?

1

A co jest takiego niezwykłego w tym co napisałem?

1
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?

0

C99 i C11, czyli po prostu C. Jak najbardziej zwykłego c.

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