logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Kopiowanie bitów ze zmiennej do zmiennej - w [C]

Fredy 06 Lut 2011 15:07 2653 11
REKLAMA
  • #1 9111818
    Fredy
    Poziom 27  
    Witam;

    Mam krótkie pytanko , jak zrobić w sposób łatwy, czytelny i ekonomiczny kopiowanie pojedyńczych bitów ze zmiennej do zmiennej.

    Załóżmy że mamy dwie zmienne X i Y. Chcę przykładowo 3 Bit zmiennej Y wpisać do 5 bitu zmiennej X.
    W Bascomie można zrobić to b.wygodnie w ten sposób X.5=Y.3 i po sprawie.

    Ale jak to zrobić w C? Próbowałem ale wszystko co stworzyłem to b.skomplikowane koszmarki , napewno da się to prościej ugryźć. Może da się jakieś makro zdefiniować do takiego kopiowania?

    Pozdrawiam
  • REKLAMA
  • #2 9111933
    lekto
    Poziom 35  
    Poczytaj o operacjach bitowych.
  • REKLAMA
  • #4 9112021
    mirekk36
    Poziom 42  
    Electix napisał:
    Można to zrobić np tak:
    
    
     x=((y&0B00001000)<<2);
     
    



    Słusznie, jeśli nie istotne są pozostałe bity w X to można tak zrobić.

    Jednak Bascomowskie X.5 = Y.3 kopiuje tylko i wyłącznie te bity nie naruszając wartości pozostałych. W takim przypadku gdyby zależało na dokładnie takiej samej operacji to trzeba by to było zrobić inaczej, np:

    
    x &= (1<<5);
    if( Y & (1<<3) ) x |= (1<<5);


    albo rozpisując to bez IFów np:

    x = ( x & ~(1<<5) ) | ( (y & (1<<3)) << 2);


    a może można jeszcze prościej? .... może ktoś podpowie ;)
  • REKLAMA
  • #5 9112032
    Fredy
    Poziom 27  
    Electix napisał:
    Można to zrobić np tak:
    
    
     x=((y&0B00001000)<<2);
     
    

    dla zmiennych 8bit licząc bity od 0 do 7 :)


    ale to chyba nie zadziała. Przecież zmienną X uszkodzisz tym przypisaniem
  • #6 9112150
    Andrzej__S
    Poziom 28  
    Nie wiem czy tak jest prościej, ale alternatywnie piąty bit zmiennej y można skopiować do trzeciego bitu zmiennej x przykładowo tak:
    
    x = y & (1<<5) ? x | (1<<3) : x & ~(1<<3);
    


    EDIT:
    Teraz zauważyłem, że miało być X.5=Y.3 :)
    
    x = y & (1<<3) ? x | (1<<5) : x & ~(1<<5);
    
  • REKLAMA
  • #7 9112245
    lekto
    Poziom 35  
    może coś takiego

    if(y & 00000100)
    x = x | 00000100;
    else
    x = x & 00000100;
  • #8 9112406
    Fredy
    Poziom 27  
    lekto napisał:
    może coś takiego

    if(y & 00000100)
    x = x | 00000100;
    else
    x = x & 00000100;


    Oczywiście że takie konstrukcje są ok (chociaż ta akurat ma błąd bo brakuje negacji w drugim warunku) ale cały czas są to b.skomplikowane rozwiązania.

    Mój problem polega na tym że potrzebuje wielokrotnie z takich operacji korzystać, mam napisany program w pierwszej wersji w Bascomie i tam to wyglądało jak przysłowiowa lala - teraz piszę w C i te wstawki z ifami mnie rozbrajają.
    Nie mówię tu o wielkości kodu lecz o wizualnym porządku. Chciałoby to się ugryźć jakimś makrem, albo funkcją aby rozwiązanie było uniwersalne.
  • #9 9112460
    lekto
    Poziom 35  
    Nie wiem jak te sprawy wyglądają w C, ale w C++ zrobiłbym makrodefinicje albo funkcje inline
  • #10 9112522
    tymon_x
    Poziom 30  
    Ja zaproponuje coś takiego :D

    #include "stdint.h"
    #include <stdio.h>
    
    struct mybits {
    	unsigned  bit0 : 1;
        unsigned  bit1 : 1;
        unsigned  bit2 : 1;
        unsigned  bit3 : 1;
        unsigned  bit4 : 1;
        unsigned  bit5 : 1;
        unsigned  bit6 : 1;
        unsigned  bit7 : 1;
    };
    
    
    int main(void){
    	uint8_t moja_zmienna1 = 0x00;
    	uint8_t moja_zmienna2 = 0x55;
    	
    	struct mybits *zmienna1 = (struct mybits *) &moja_zmienna1;
    	struct mybits *zmienna2 = (struct mybits *) &moja_zmienna2;
    
    	zmienna1->bit4 = zmienna2->bit6;
    
    	printf("Nowa wartość HEX moja_zmienna1: 0x%X", moja_zmienna1);
    	return 0;
    }

    Pod kompa pisane, łatwo dostosować.
  • Pomocny post
    #11 9112549
    Andrzej__S
    Poziom 28  
    Jak masz podaną taką formułę:
    
    x = y & (1<<3) ? x | (1<<5) : x & ~(1<<5);
    

    to napisanie makra nie jest przecież większym problemem:
    
    #define COPY_BIT(t,tb,s,sb) t = s & (1<<(sb)) ? t | (1<<(tb)) : t & ~(1<<(tb))
    /*
    t  = zmienna do której bit jest kopiowany
    tb = pozycja bitu w zmiennej
         do której bit jest kopiowany
    s  = zmienna z której bit jest kopiowany
    sb = pozycja bitu w zmiennej
         z której bit jest kopiowany
    */
    
    // użycie makra
    COPY_BIT(x,5,y,3);
    
    


    Jeśli nazwa makra jest jeszcze za długa to możesz zmienić na krótszą, jaka będzie Ci odpowiadała.
  • #12 9112988
    mirekk36
    Poziom 42  
    Fredy napisał:
    Chciałoby to się ugryźć jakimś makrem, albo funkcją aby rozwiązanie było uniwersalne.


    No to właśnie tak trzeba ugryźć, o strukturach z polami bitowymi już wspominałem wcześniej, że warto się zainteresować, a tutaj nawet koledzy podali konkretne przykłady jak to zastosować i ze struktutami i z definicjami dla preprocesora.
REKLAMA