2xBytes - Bitweise alternierend zusammenfügen

Gast #6439032
Lesenswert?
• ▲
▼
So als Lösungsansatz (mein Assembler ist etwas eingestaubt).
Eine Schiebeoperation sorgt dafür, dass das rausgeschobene Bit im Carry 
landet. Dann kann man ein "AddWithCarry" mit 0 machen, und das Ergebnis 
entsprechend weiterschieben.
Das Ganze in einer kleinen Schleife.
#6439034
Lesenswert?
• ▲
▼
vllt so? schrieb:
> for i= 0 bis 7
>
> Word(16Bit) = Word(16Bit) | ((firstByte>>(7-i))&1)
> Word(16Bit) = Word(16Bit)<<1
>
> Word(16Bit) = Word(16Bit) | ((secondByte>>(7-i))&1)
> Word(16Bit) = Word(16Bit)<<1
>
> EndFor

uint16_t u16Result = 0;
uint8_t u8A = 0b10101010;
uint8_t u8B = 0b01010101;

for(uint8_t i = 0; i < 8; i++){
  u16Result |= u8A & 1;
  u8A >> 1;
  u16Result << 1;

  u16Result |= u8B & 1;
  u8B >> 1;
  u16Result << 1;
}
#6439051
Lesenswert?
• ▲
▼
Ben S. schrieb:
> uint16_t u16Result = 0;
> uint8_t u8A = 0b10101010;
> uint8_t u8B = 0b01010101;
>
> for(uint8_t i = 0; i < 8; i++){
>   u16Result |= u8A & 1;
>   u8A >> 1;
>   u16Result << 1;
>
>   u16Result |= u8B & 1;
>   u8B >> 1;
>   u16Result << 1;
> }

Fehler, dies getestet:
1
uint16_t combine (uint8_t u8A, uint8_t u8B) {
2
  uint16_t u16Result = 0;
3

4
  for (uint8_t i = 0; i < 8; i++) {
5
    u16Result |= u8A & 1;
6
    u8A >>= 1;
7
    u16Result <<= 1;
8

9
    u16Result |= u8B & 1;
10
    u8B >>= 1;
11
    u16Result <<= 1;
12
  }
13

14
  return u16Result;
15
}
Gast #6439150
Lesenswert?
• ▲
▼
Ohne Schleife:
1
int16_t shuffle16(std::uint8_t a, std::uint8_t b)
2
{
3
  uint16_t val = static_cast<uint16_t>(a) << 8 | b;
4
  uint16_t mask;
5
  mask = (val ^ (val >> 4)) & 0x00f0;
6
  val = val ^ mask ^ (mask << 4);
7
  mask = (val ^ (val >> 2)) & 0x0c0c;
8
  val = val ^ mask ^ (mask << 2);
9
  mask = (val ^ (val >> 1)) & 0x2222;
10
  val = val ^ mask ^ (mask << 1);
11

12
  return val;
13
}
Gast #6439585
Lesenswert?
• ▲
▼
Ben S. schrieb:
> uint16_t combine (uint8_t u8A, uint8_t u8B) {
>   uint16_t u16Result = 0;
>
>   for (uint8_t i = 0; i < 8; i++) {
>     u16Result |= u8A & 1;
>     u8A >>= 1;
>     u16Result <<= 1;
>
>     u16Result |= u8B & 1;
>     u8B >>= 1;
>     u16Result <<= 1;
>   }
>
>   return u16Result;
> }

Die Schieberei am Ende liefert falsches Ergebnis.
1
   for (uint8_t i = 0; i < 8; i++) {                                    
2
      u16Result <<= 1;                                                  
3
      u16Result |= u8A & 1;                                             
4
      u8A >>= 1;  
5
                                                      
6
      u16Result <<= 1;                                                                                                           
7
      u16Result |= u8B & 1;                                             
8
      u8B >>= 1;                                                        
9
   }
(Firma: Funkenflug Industries) #6442285
Lesenswert?
• ▲
▼
In Assembler würde ich das angesichts heutiger Prozessoren
"Speedcode-Style" schreiben, also 32 einfache Bitshifts
über Carry, fertig. Vielleicht nicht ganz so elegant wie mit
einer Schleife, aber moderne Prozessoren mit ihren großen
Caches und Optimierungen dürften das in wenigen Takten
erledigt haben und die paar Byte mehr Speicherplatzbedarf
fallen heute nicht mehr auf.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.