Umwandlung von 8bit zu 7bit

Schnelle objektorientierte, kompilierende Programmiersprache.
mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von mfro » Mi Mär 05, 2014 10:28 am

OT: da hab' ich doch gleich wieder einen Klugscheißeransatz, als Tip aus der Praxis getarnt ;)

Warum schreibe ich

Code: Alles auswählen

x &= ~0x80;
und nicht

Code: Alles auswählen

x &= 0x7F;
??

Weil ich finde, daß man Programme so schreiben sollte, daß sie "selbstkommentierend" sein sollten.
Wenn (m)ein Hirn "0x80" liest, schaltet es sofort in den "Bitpfriemlermodus" und sagt: aha, Bit 7 ist gemeint. "&= ~" sagt: "ausknipsen".

Bei

Code: Alles auswählen

x &= 0x7F;
mag das noch einigermaßen offensichtlich sein. Aber wenn man so schreibt, sieht man nicht unmittelbar, daß das

Code: Alles auswählen

x |= 0x80;
die inverse Operation dazu ist ("0x80": Bit 7, "|=": "anknipsen").

Ist Geschackssache, man könnte auch

Code: Alles auswählen

x &= ~(1 << 7);
schreiben, dann wäre die 7 direkt ersichtlich. Dem Compiler ist's egal, der macht aus allem denselben Code (er erkennt, daß rechts vom Gleichheitszeichen eine Konstante steht und rechnet die gleich aus).
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Umwandlung von 8bit zu 7bit

Beitrag von Xin » Mi Mär 05, 2014 10:50 am

mfro hat geschrieben:Warum schreibe ich

Code: Alles auswählen

x &= ~0x80;
??

Weil ich finde, daß man Programme so schreiben sollte, daß sie "selbstkommentierend" sein sollten.
Wenn (m)ein Hirn "0x80" liest, schaltet es sofort in den "Bitpfriemlermodus" und sagt: aha, Bit 7 ist gemeint. "&= ~" sagt: "ausknipsen".
+1

Diese kleinen semantischen Feinheiten sollte man sich durchaus überlegen. Wenn man ausdrücken möchte, dass man Bit 8 löschen möchte, ist das genau das, was man schreiben sollte.
Aber möchte man eigentlich das 8. Bit löschen?

Ich finde &= 0x7F hier nicht verkehrt, denn niemand garantiert mir, dass das char 8 Bit groß ist - eventuell sind noch Bit 9, 10 usw. gesetzt. Da die Aussage des Algorithmus doch ist, dass man nur die rechten 7 Bit haben möchte, halte ich &= 0x7F für die fehlertolerantere Variante und auch für die Variante, die genauer aussagt, was der Programmierer eigentlich möchte: Die 7 rechten Bit und keine anderen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von chris_1981_ » Mo Mär 24, 2014 9:50 pm

Hallo zusammen,

ich habe lange keine Zeit gehabt, mich weiter mit diesem Thema zu beschäftigen, doch nun geht es mit kleinen Schritten wieder weiter. In der Zeit habe ich aber ein weiteres Buch über C gelesen, C für Dummies, ja ich bin verzweifelt.

Mir ist natürlich klar, dass ich erst einmal versuchen sollte von ASCII nach PDU zu konvertieren anstatt umgekehrt, aber mir fehlt aktuell das Verständnis, wenn Beispielsweise aus der Seriellen Schnittstelle folgender String übermittelt wird:

Code: Alles auswählen

char string[] = "48616C6C6F"
wie ich daraus "den eigentlichen Hex" Wert mache, denn ich denke ich muss ja den Hex Wert wieder aus dem String bilden, um daraus wieder ASCII zu machen?

Ich bin wie folgt angefangen:
Ich weiß es nervt dass ich immer versuche "einzelne" Schritte zu gehen, aber ich mache es trotzdem.

Code: Alles auswählen

int u;
ins s;

f[] = "48";

u = ((f[0]>>4) & 0x0F);
s = (f[1] & 0x0F);

printf (" %i and %i \n", u, s);
Ausgabe: 3 and 8
Ich denke was ich dort mache ist völliger Schwachsinn.

Mir geht es um die Richtung, nicht um die Lösung!

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von mfro » Di Mär 25, 2014 7:58 am

Ich gehe jetzt einfach mal davon aus, daß Du - auch wenn das aus deinem Beitrag nicht unmittelbar zu entnehmen ist - aus einem Hex-String die Binärdarstellung ermitteln willst?
chris_1981_ hat geschrieben:

Code: Alles auswählen

int u;
ins s;

f[] = "48";

u = ((f[0]>>4) & 0x0F);
s = (f[1] & 0x0F);

printf (" %i and %i \n", u, s);
Ausgabe: 3 and 8
Das Ergebnis hat hier nur zufälligerweise annähernd mit dem gewünschten zu tun.
chris_1981_ hat geschrieben: Ich denke was ich dort mache ist völliger Schwachsinn.
Das denke ich leider auch ;).

Nehmen wir mal auseinander, was Du da treibst.

Code: Alles auswählen

u = ((f[0]>>4) & 0x0F);
Das nimmt die erste Ziffer aus dem Hex-String (das ASCII-Zeichen "4", entspricht in Binärdarstellung 52 = 0x34 = 0b00110100) und schiebst sie um vier Stellen nach rechts. Dabei kommt 0b00000011 = 3 raus.

Das ist zwar eine schöne Rechnung, hat aber überhaupt nichts mit dem zu tun, was Du erreichen willst - aus der "4" (ASCII) eine 4 (binär) zu machen.

Eine Hex-Ziffer ist ein Zeichen im ASCII-Code mit dem Wertebereich "0"-"9" (entspricht den ASCII-Codes 0x30-0x39 bzw. 40-49 dezimal) und "A"-"F" (entspricht den ASCII-Codes 0x41-0x46 (65-70 dezimal). Es geht jetzt also darum "0" - "9" (40 - 49) auf 0 - 9 und "A" - "F" (65 - 70) auf 10 - 15 abzubilden. Ich bastel' dir dazu mal eine kleine Funktion (die so natürlich nur für eine Ziffer funktioniert und denkbar umständlich ist, aber ich hoffe, daß das Prinzip so leichter zu verstehen ist):

Code: Alles auswählen

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int hex2bin(char c)
{
    switch (c)
    {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return c - '0'; // man könnte hier natürlich auch "c - 40;" schreiben, aber so sieht man, was gemeint ist
            break;

        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
            return 10 + c - 'A';  // man könnte hier natürlich auch "10 + c - 65;" schreiben, aber so sieht man, was gemeint ist
            break;

        default:
            fprintf(stderr, "%c ist keine Hex-Ziffer\n", c);
            exit(1);
    }
}   

int main(int argc, char *argv[])
{
    int i;

    char f[] = "48FX";

    for (i = 0; i < strlen(f); i++)
        printf ("f[%d] = %i\n", i, hex2bin(f[i]));
}

Erst wenn das erledigt ist, kannst Du (wie Du ja ansatzweise schon versucht hast) aus den zwei 4-Bit Zahlen, die die Hex-Ziffern darstellen, eine 8-Bit Zahl "zusammenschieben".
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von chris_1981_ » Di Apr 01, 2014 3:57 pm

Hallo Mfro,

ich bin deinem Beispiel gefolgt, vielen dank für deine Mühen.
Ich habe eigentlich gedacht, dass ich mit einer einzigen bzw. mit mehreren auf einander folgenden Bit Verschiebungen die Problematik von einem Ascii Array in Hex Format umgehen kann.

Ich habe dein Schnipsel ausprobiert und dieser funktioniert tadellos, es wird auch verständlich was passiert.
Hier ein Beispiel, entschuldigt die Schrittweise Verarbeitung hilft mit bei der Lösung viel, viel besser.

Code: Alles auswählen

    y = hex2bin(f[0]);

    printf ("f[%d] = %i\n", i, hex2bin(f[0]));

    i = 1;

    z = hex2bin(f[1]);

    printf ("f[%d] = %i\n", i, hex2bin(f[1]));

    s = y << 4 | z;

    printf ("f[] INT = %i\n", s);
    printf ("f[] HEX = %02x\n", s);
    printf ("f[] CHAR = %c\n", s);

Ergebnis:
f[0] INT = 4
f[1] INT = 8
f[] INT = 72
f[] HEX = 48
f[] CHAR = H
Vielen Dank!

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von chris_1981_ » Di Apr 01, 2014 8:02 pm

Übrigens hast du geschrieben:

Code: Alles auswählen

return c - '0'; // man könnte hier natürlich auch "c - 40;" schreiben, aber so sieht man, was gemeint ist
soll das nicht heißen: c- 48; ?

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von mfro » Mi Apr 02, 2014 5:44 am

chris_1981_ hat geschrieben: soll das nicht heißen: c- 48; ?
Natürlich. Oder c - 0x30.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Umwandlung von 8bit zu 7bit

Beitrag von Xin » Do Apr 03, 2014 9:27 am

Und genau deswegen ist c-'0'; die einzige sinnvolle Schreibweise, weil sie klar beschreibt, was gemeint ist und 48 und 0x30 einfach nur Magic-Numbers sind, wo niemand weiß, warum man diesen Wert da nun abzieht. :-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von chris_1981_ » Mo Apr 28, 2014 9:40 pm

Hallo zusammen,

ich weiß es ist mehr als lächerlich, dass ich immer noch an meinem Problem hänge, aber ehrlich gesagt habe ich fast gar nicht mehr nach meinem letzten Kommentar an dieser Funktion gearbeitet.

als Ergebnis bekomme ich aktuell:

Code: Alles auswählen

ffffffd7 
ffffffa0 
ffffffd4 
ffffffa9 
03 
19 
ffffffcb 
00 
ffffffee 
39 
ffffffbd 
2c 
07 
ffffffa5 
ffffffdb 
00 
ffffffa0 
ffffffe9 
18 
ffffffcd 
0e 
ffffff9b 
fffffff5 
00 
ffffffe9 
76 
ffffffbb 
2c 
07 
ffffffbd 
ffffffcd 
00 
ffffffe6 
ffffffb2 
1b 
00 
Meine Frage warum ergibt folgender Code
das oben stehende Ergebnis:

Code: Alles auswählen

char *oct2sep (char *sept, const char *text)
{
    int pos = 0;

    do
    {
        if (*text & 0x80)
        {
            printf ("Bit 8 ist gesetzt \n");
            break;
        }

        *sept = *text >> pos;
        *sept |= (*(text + 1) & mask[pos]) << (7 - pos);

        printf ("%02x \n", *sept);
        if (pos != 7) /* nach 7 Zeichen haben wir eins eingespart */
        sept++;

        pos = (pos + 1) % 8;

    }while (*text++);
    sept = '\0';
    
}
Warum werden die einzelnen Zeichen mit ffffff aufgefüllt?

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Umwandlung von 8bit zu 7bit

Beitrag von chris_1981_ » Di Apr 29, 2014 7:31 pm

Hallo zusammen,

Ich habe den Fehler gefunden, man ey, wer lesen kann ist klar im Vorteil.
Sobald ich aus dem Char ein unsigned Char mache, funktioniert es.

Endschuldigt bitte die Frage.

Antworten