"bitstring" verketten



  • Hi Leute,

    es gibt doch bestimmt die Möglichkeit, das ich 2 Bitstrings "verketten" kann, oder?

    Ich stehe wahrscheinlich wieder etwas auf dem Schlauch. 🙃

    So sieht das Ziel aus:

    Ich möchte gerne aus Zwei uint32_t Bitstrings einen neuen uint64_t Bitstring erstellen.

    Dabei soll der neue uint64_t Bitstring zuerst mit dem ersten Bit des ersten Bitstrings beginnen, dann soll das erste Bit des zweiten Bitstrings folgen. Nun kommt das zweite Bit des ersten Bitstrings.
    Eine Art Reißverschluß also 🙂

    Hier noch mal zum Verständnis:

    uint32_t bitstring1=0b11111111111111111111111111111111
    uint32_t bitstring2=0b00000000000000000000000000000000

    soll werden zu --->

    uint64_t bitstring3=0b1010101010101010101010101010101010101010101010101010101010101010

    es gibt bestimmt eine ganz einfache Lösung😟 aber wie mache ich das?

    Bitte helft mir

    Gruß Chris



  • uint32_t ist eine Zahl und kein String.



  • std::uint64_t magic(std::uint32_t a, std::uint32_t b)
    {
    	std::uint64_t result{};
    	uint32_t mask{ 1u << 31u };
    	for (unsigned i{}; i < 32; ++i) {
    		result <<= 2;
    		result |= (!!(a & mask) << 1);
    		result |= !!(b & mask);
    		mask >>= 1;
    	}
    	return result;
    }
    


  • Ja, genau richtig. Und jede Zahl besteht aus Bits.👍🏻

    Die Rede ist hier von BITstrings(0b...), bitte nicht mit Strings verwechseln.😵

    Danke für die Anteilnahme 🙂



  • @Hamstaaa sagte in "bitstring" verketten:

    Die Rede ist hier von BITstrings(0b...), bitte nicht mit Strings verwechseln.

    Das ist kein ... string. Das ist ein integer literal.

    https://en.cppreference.com/w/cpp/language/integer_literal



  • @Swordfish

    Danke, wird gleich ausprobiert 🙂 Und ich lasse mich immer wieder gerne eines besseren belehren.



  • siehe edit. der shift der maske muss ans ende 🤦🏽♂



  • void magic(uint32_t a, uint32_t b)
    {
      
    	uint64_t result64=0;
    	uint32_t mask = 1u << 31u;
    
    	for (int i=0; i<32; i++) 
      {
    		result64 <<= 2;
    		result64 |= (!!(a & mask) << 1);
    		result64 |= !!(b & mask);
    		mask >>= 1;
    	}
    
    printf("magicRESULT64: %" PRIu64 "\n", result64);
    return;
    }
    

    Danke Swordfish!

    nach einigen Anpassungen am Code konnte ich dein Programm auf meinem ESP32 Microcontroller testen und er funktioniert super!

    Nur zu doof, dass ich feststellen musste, dass das ets_printf von Espressif bei dem uint64_t nicht klar kommt.

    tausche ich ets_printf gegen printf aus funzt alles wunderbar!!!

    als zeigt er mir folgendes an: RESULT64: 12297829382473034410

    Mein Taschenrechner nimmt die Zahl nicht mehr (zum umrechnen) schätze mal das kommt hin?!



  • @Hamstaaa sagte in "bitstring" verketten:

    als zeigt er mir folgendes an: RESULT64: 12297829382473034410

    Wie soll das jemand wissen wenn Du die Eingabe nicht nennst.



  • @Swordfish Die Eingabe steht im ersten Post 🙂

    uint32_t bitstring1=0b11111111111111111111111111111111
    uint32_t bitstring2=0b00000000000000000000000000000000

    soll werden zu --->

    uint64_t bitstring3=0b1010101010101010101010101010101010101010101010101010101010101010

    als a habe ich also "bitstring1" und als b "bitstring2" verwendet .



  • uint64_t shuffle(uint32_t a, uint32_t b)
    {
    	uint64_t result = static_cast<uint64_t>(a) << 32 | b;
    	result = (result & 0x00000000ffff0000) << 16 | (result >> 16) & 0x00000000ffff0000 | result & 0xffff00000000ffff;
    	result = (result & 0x0000ff000000ff00) << 8 | (result >> 8) & 0x0000ff000000ff00 | result & 0xff0000ffff0000ff;
    	result = (result & 0x00f000f000f000f0) << 4 | (result >> 4) & 0x00f000f000f000f0 | result & 0xf00ff00ff00ff00f;
    	result = (result & 0x0c0c0c0c0c0c0c0c) << 2 | (result >> 2) & 0x0c0c0c0c0c0c0c0c | result & 0xc3c3c3c3c3c3c3c3;
    	result = (result & 0x2222222222222222) << 1 | (result >> 1) & 0x2222222222222222 | result & 0x9999999999999999;
    
    	return result;
    }
    
    


  • @Caligulaminus Das ist schön.



  • @Caligulaminus

    Ja das ist schön aber gibts es das auch ohne static_cast?

    Die Funktion von Swordfish hat ja funktioniert, aber die bytes die Raus kommen stimmen irgendwie nicht.

    Muss man da evtl was wegshiften oder habe ich etwas übersehen?



  • @Hamstaaa sagte in "bitstring" verketten:

    aber die bytes die Raus kommen stimmen irgendwie nicht.

    Die stimmen.

    https://www.mobilefish.com/services/big_number/big_number.php



  • @Swordfish

    habe ich auch grade mal eingegeben komisch, schmeißt der Taschenrechner
    -6.148.914.691.236.517.206‬ raus bei 10101010... weil der signed rechnet und ich im code unsigned?!



  • @Hamstaaa sagte in "bitstring" verketten:

    -6.148.914.691.236.517.206

    Es ist dasselbe bitmuster.



  • @Swordfish

    Hey Swordfish.

    dein Codeschnipsel tut seinen Dienst 🙂

    Aber eine Frage hätte ich wohl noch....

    Ich habe jetzt einen Binärwert aus deinem Programm. Und ich habe eine Maske (10101010)

    x = 0b 0110 1101 (109)
    x2 = 0

    Wie bekomme ich es jetzt hin, dass er mir, anhand der Maske den maskierten Inhalt aus "x" in "x2" schreibt?
    mit einem normalen "&" komme ich da nicht weiter.

    also so:

    x  in    = 0110 1101
    maskex   = 1010 1010  // 
    x2  out  = 0000 0110 (6)


  • @Caligulaminus sagte in "bitstring" verketten:

    uint64_t shuffle(uint32_t a, uint32_t b)
    {
    	uint64_t result = static_cast<uint64_t>(a) << 32 | b;
    	result = (result & 0x00000000ffff0000) << 16 | (result >> 16) & 0x00000000ffff0000 | result & 0xffff00000000ffff;
    	result = (result & 0x0000ff000000ff00) << 8 | (result >> 8) & 0x0000ff000000ff00 | result & 0xff0000ffff0000ff;
    	result = (result & 0x00f000f000f000f0) << 4 | (result >> 4) & 0x00f000f000f000f0 | result & 0xf00ff00ff00ff00f;
    	result = (result & 0x0c0c0c0c0c0c0c0c) << 2 | (result >> 2) & 0x0c0c0c0c0c0c0c0c | result & 0xc3c3c3c3c3c3c3c3;
    	result = (result & 0x2222222222222222) << 1 | (result >> 1) & 0x2222222222222222 | result & 0x9999999999999999;
    
    	return result;
    }
    
    

    Deinen Code habe ich natürlich auch ausprobiert!

    Leider ohne Erfolg. Erst gab es "suggest parentheses around arithmetic in operand of '|' [-Werror=parentheses]" Fehler (Er markiert dabei die "&" Operator) und als ich mehr Klammern gesetzt habe, kam nur wirres Zeug raus.



  • @Hamstaaa sagte in "bitstring" verketten:

    Leider ohne Erfolg. Erst gab es "suggest parentheses around arithmetic in operand of '|' [-Werror=parentheses]" Fehler und als ich mehr Klammern gesetzt habe, kam nur wirres Zeug raus.

    Das ist ja nur eine Warnung. Hast du es in dem Zustand nicht ausprobiert? Ich tippe mal, dass du danach die Klammern falsch gesetzt hast.

    (Ich hab allerdings den Code nicht im Detail nachvollzogen, vielleicht ist er ja wirklich falsch.)



  • @Bashar sagte in "bitstring" verketten:

    @Hamstaaa sagte in "bitstring" verketten:

    Leider ohne Erfolg. Erst gab es "suggest parentheses around arithmetic in operand of '|' [-Werror=parentheses]" Fehler und als ich mehr Klammern gesetzt habe, kam nur wirres Zeug raus.

    Das ist ja nur eine Warnung. Hast du es in dem Zustand nicht ausprobiert? Ich tippe mal, dass du danach die Klammern falsch gesetzt hast.

    (Ich hab allerdings den Code nicht im Detail nachvollzogen, vielleicht ist er ja wirklich falsch.)

    Hat es nicht seinen Grund wenn so eine Warnung kommt? Zumal die "Warnung" zum build abbruch führt?!

    Eventuell kannst du den Code von Caligulaminus ja c++ entsprechend umgestalten 🙂


Log in to reply