Forum: PC-Programmierung Parity-Funktion in C


von Da Mo (Gast)


Lesenswert?

Guten Abend!

Kann mir bitte jemand den folgenden Quelltext für eine Parity-Funktion 
in C, mit verständlichen Worten und Schritt für Schritt erklären? Ich 
bin noch ziemlicher Anfänger und bin in C noch extem unsicher.

Ich bedanke mich schon im Voraus für eine hilfreiche Antwort!!!

Grüße
Dominik

Quelltext:

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

int main(void)
{
 unsigned char data=0x7F;
 unsigned char mask= 0x01;
 unsigned char counter= 0;
 unsigned char i;

 for (i= 0; i< 7; i++)
 {
  if(mask&data)
  counter++;
  mask<<=1;
 }
 if(counter%2)
 data|=(1<<7);

 printf("counter=%d, data=0x%x\n", counter, data);
 system("pause");
 return 0;
}

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:

> Kann mir bitte jemand den folgenden Quelltext für eine Parity-Funktion
> in C, mit verständlichen Worten und Schritt für Schritt erklären? Ich
> bin noch ziemlicher Anfänger und bin in C noch extem unsicher.

Kannst du ein bischen konkreter werden.
Welche Teile verstehst du und welche Teile verstehst du nicht.

AN und für sich ist die Funktionalität nicht schwer zu verstehen.
Die einzig 'ungewöhnlichen Funktionen' die du mglw. nicht kennst sind & 
und  <<=

das erste: &    ist eine binäre verundung. dabei werden einfach die bits 
an den jeweils korrespondierenden Stellen einer UND Operation unterzogen

    bit 1   bit 2   ergebnis
  ---------------------------
     0        0        0
     0        1        0
     1        0        0
     1        1        1

das Ergebnisbit ist nur dann 1, wenn bit1 UND bit2 1 sind.

Hast du also 2 Zahlen in Binärschreibweise

Zahl1     10001011
Zahl2     00011010

dann wendest du einfach die UND Operation auf jede Spalte an. Das 
Ergebnis ist

Ergebnis  00001010

und die andere Operation ist <<=
Die besteht aus 2 Teilen, so wie auch += oder *=
Auf der einen Seite die Operation selber und auf der anderen Seite dem 
=, welche die Operation als Kurzschreibweise nach dem Muster

     a op= b     <===>   a = a op b

kennzeichnet
(op ist die Operation, also bei +:   a += b   <==> a = a + b)

dh. die eigentliche Frage lautet: was macht <<

Und das macht genau das, wonach es aussieht: es verschiebt die 
Binärrepresentierung der Bits einer Zahl nach links:
a << b    verschiebt das Bitmuster von a um b Stellen nach links wobei
          von rechts 0 Bits nachrücken

  10001011  << 1   ergibt also   00010110
  10001011  << 2   ergibt also   00101100
  10001011  << 3   ergibt also   01011000
  10001011  << 4   ergibt also   10110000
  10001011  << 5   ergibt also   01100000
  usw.


% ist die Modulo Operation, welche den Rest berechnet. So wie in: Eine 
Muter hat 14 Äpfel und 3 Kinder. Wenn jedes Kind gleich viele ganze 
Äpfel bekommt, wieviele bleiben der Mutter übrig

     14 % 3 ----> 2

Der Mutter bleiben 2 Äpfel übrig.


Ach. Du kommt ja noch ein ODER vor.
a |= b   ist wieder die Kurzschreibweise für  a = a | b

und ein binäres ODER funktionert wie ein binäres UND, nur halt mit ODER

   bit 1   bit 2   ergebnis
 ----------------------------
     0       0        0
     0       1        1
     1       0        1
     1       1        1

Das ergebnisbit ist genau dann 1, wenn enweder bit1 ODER bit2 ODER beide 
1 sind.


Mit den Zutaten solltest du das selbst entschlüsseln können. Hilfreich 
ist auch in einem Debugger den Code durchzusteppen und deine Analysen 
mit dem zu vergleichen, das dein Computer tatsächlich macht.

von Da Mo (Gast)


Lesenswert?

Vorerst vielen Dank Herr Buchegger!

Ich schreibe mit dem Programm Dev-C++. Ich weiß aber nicht ob dieses 
einen Debugger beinhaltet.

von DirkB (Gast)


Lesenswert?

Dominik M. schrieb:
> Ich schreibe mit dem Programm Dev-C++.

Hast du auch die neuste Version?
Im Sommer sind nach 6 Jahren Stillstand ein paar neue Versionen 
rausgekommen.

Dominik M. schrieb:
> Ich weiß aber nicht ob dieses
> einen Debugger beinhaltet.

Auf dem Bild auf Wikipedia kann man ein Debug-Menü sehen.

von Da Mo (Gast)


Lesenswert?

Nein, ich habe die Version 4.9.9.2 installiert (verwenden diese Version 
auch in der Schule)!?

von Da Mo (Gast)


Lesenswert?

Die if - Bedingung im Ausschnitt aus dem Quelltext, vergleicht also 
bitweise oder?

for (i= 0; i< 7; i++)
{
 if(mask&data)
 counter++;
 mask<<=1;
}

von DirkB (Gast)


Lesenswert?

In mask ist nur ein Bit gesetzt (am Anfang das erste). Diese Maske wird 
bitweise verundet mit dem Datenbyte data (wie oben beschrieben). Wenn 
das Ergebnis ungleich 0 ist, ist das entsprechende Bit in data gesetzt.

Danach schiebst du das gesetzte Bit in mask um eine Stelle weiter.

von Da Mo (Gast)


Lesenswert?

Guten Abend,

ich habe den Quellcode (für mich) etwas verständlicher gestaltet. Was 
ist die eigentliche Aufgabe dieser PARITY-Funktion (Vergleich-Funktion)?

Die gesetzten Bits werden gezählt und wenn dabei eine ungerade Anzahl 
heraus kommt, wird das achte Bit gesetzt um eine gerade Anzahl von 
gesetzten Bits zu bekommen!?

Das heißt es werden nur 7 Bits kontrolliert und das achte Bit als 
Kontrollbit verwendet!?

Richtig? Für was soll das gut sein?

Sorry für die etwas Laienhafte Schreibweise aber ich bin noch fast ganz 
am Anfang. :-)


//PARITY - Funktion

#include <stdio.h>

int main(void)
{
 unsigned char data=0x46;
 unsigned char mask=0x01;
 unsigned char counter=0;
 unsigned char i;

 for (i=0; i<7; i++)
 {
  if(mask&data)
  {
  counter++;
  }
  mask=mask<<1;
 }

 if(counter%2) //erfüllt,wenn counter durch 2 ohne Rest nicht teilar ist
 {
  data=data|(1<<7); //An der 7 Stelle von data, wird ein Bit gesetzt
 }

 printf("counter=%d, data=0x%x\n\n", counter, data);
 system("pause");
 return 0;
}

von dall (Gast)


Lesenswert?


von Da Mo (Gast)


Lesenswert?

Wie funktioniert jetzt die Überprüfung auf EVEN oder ODD?

von Karl H. (kbuchegg)


Lesenswert?

Überleg mal, welchen Zweck wohl

 if(counter%2)

haben wird. Was verrät dir der Rest der bei einer Division durch 2 
entsteht?

von Da Mo (Gast)


Lesenswert?

Dieser verrät mir, dass eine ungerade Anzahl von Bits gesetzt ist.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

naja, du überträgst halt irgendwelche Daten, und zusätzlich zu den Daten 
überträgst du, daß die Quersumme dieser Daten grade (oder ungrade) ist.

Der Empfänger liest die Daten ein, bildet sich selber die Quersaumme, 
und vergleicht die selbst ermittelte Quersumme mit der Übermittelten 
Quersumme.

Sollte  es Abweichungen geben, so ist das ein Indiz frü einen Fehler. 
Genauer: Wahrscheinlich ist ein Einzelfehler aufgetreten.

Die Paritätsprüfung ist allerdings nur ein mäßig guter Prüfmechanismus. 
Wenn nämlich 2 Bit "kippen" (als anstelle einer 0 eine 1 übertragen 
wird, bzw. anstelle einer 1 eine 0), dann siehst du das mit dieser 
Quersumme halt NICHT mehr. Ein Doppelfehler wird also nicht erkannt.

Wenn du eine sehr sichere Datensituation haben möchtest, mußt du dann zu 
ECC (Error correction code) greifen.


ALLERDINGS ist das eine Frage des Aufwandes: In mäßig moderaten 
Umgebungen ist möglicherweise schon das Auftreten eines Einzelfehles 
recht unwahrscheinlich, und ein simples ""Parity check" reicht schon 
aus.

von Karl H. (kbuchegg)


Lesenswert?

Ich merk gerade, dass ich deine (Dominik M.) Frage falsch verstanden 
habe. Du wolltest wissen "was mach ich jetzt mit dieser Paritätsinfo". 
Sorry für das Missverständnis.

von Da Mo (Gast)


Lesenswert?

@ Karl Heinz Buchegger

Das ist doch kein Problem. Ich bin sehr froh, dass ich Hilfe von euch 
bekomme!

@ Forum

Ich werde jetzt versuchen, diese Sender- und Empfängerkontrolle zu 
programmieren. Bin mir sehr unsicher, wie ich anfangen soll. Ich werde 
versuchen, es mit einer Sender- und Empfängerfunktion umzusetzen.

von Karl H. (kbuchegg)


Lesenswert?

Teile deine jetzige Funktionalität in 2 Teile auf:
Eine Funktion die die Parität berechnet.
Eine 2-te Funktion, die für eine gerade Parität sorgt.


Der Sender sendet dann immer Datenbytes die eine gerade Parität haben. 
Der Empfänger benutzt die erste Funktion um die Parität des empfangenen 
Bytes festzustellen. Die muss daher logischerweise gerade sein, denn der 
Sender hat ja dafür gesorgt, dass das so ist. Wenn es je vorkommt, dass 
der Empfänger ein Byte mit ungerader Parität empfängt, gab es 
offensichtlich einen Übertragungsfehler.

Die Umkehrung gilt allerdings nicht (wie WV schon ausgeführt hat). Nur 
weil die Parität stimmt, bedeutet das nicht, dass es keinen 
Übertragungsfehler gegeben hat.

von Da Mo (Gast)


Lesenswert?

Kann man eine 0 setzen, wie man es mit einer 1 macht?

data=data|(1<<7); // Parity - Bit an Stelle 7 setzen

von Karl H. (kbuchegg)


Lesenswert?


von Da Mo (Gast)


Lesenswert?

Ich habe ein Programm mit Sender- und Empfängerfunktion geschrieben. An 
die Senderfunktion, wird eine Hexzahl übergeben. In dieser wird die 
Hexzahl auf "gerade" oder "undgerade" geprüft. Wenn "ungerade" dann wir 
ein PARITY - Bit an der 7 Stelle gesetzt. Diese neue Hexzahl mit PARITY 
- Bit, wird jetzt an die Empfängerfunktion übergeben.

Wie kann ich jetzt in der Empfängerfunktion auf EVEN oder ODD prüfen? 
Mein Verständnisproblem, liegt bei EVEN und ODD. Die Überprüfung auf 
"gerade" oder "ungerade", funktioniert ja wie in der Senderfunktion.


//PARITY - Funktion (Sender, Empfänger)

#include<stdio.h>

/*********************************************************************** 
*******/
unsigned char send(unsigned char);
void receive(unsigned char);
/*********************************************************************** 
*******/
int main(void)
{
 unsigned char data=0x07;
 unsigned char y;

 y=send(data);
 receive(y);

 system("pause");
 return 0;
}
/*********************************************************************** 
*******/
unsigned char send(unsigned char x)
{
 unsigned char mask=0x01;
 unsigned char counter=0;
 unsigned char i;

 for(i=0; i<7; i++)
 {
  if(x&mask)
  {
   counter++;
  }
  mask=mask<<1;
 }

 if(counter%2)
 {
  x=x|(1<<7);
 }
 return x;
}
/*********************************************************************** 
*******/
void receive(unsigned char y)
{

 printf("Die uebertragene Hexzahlt lautet: 0x%x\n\n", y);
}
/*********************************************************************** 
*******/

von DirkB (Gast)


Lesenswert?

Lies dir noch mal durch, was  Karl Heinz Buchegger am 15.11.2011 um 
16:43 schreib.

Du brauchst also eine Funktion, die die Parität berechnet und dann 0 
oder 1 zurückgibt. Die kann z.B parity() heißen.

Und dann brauchst du noch eine Funktion die eine bestimmte Parität 
erzeugt.
Die kann z.B parity_even() heißen. Diese ruft parity() auf und erzeugt 
immer eine Gerade Parität

In der Senderoutine rufst du parity_even() auf und in der 
Empfangsroutine rufst du parity() auf. Diese muss dann als Ergebnis even 
zurück geben.

Damit du mit dem empfangenen Zeichen arbeiten kannst, musst du 
allerdings noch die Paritätsinformation löschen.
1
zeichen &= ~(1<<7);

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:

> Wie kann ich jetzt in der Empfängerfunktion auf EVEN oder ODD prüfen?

Indem du dieselbw Parity Berechnung beim Empfänger wieder machst. Dort 
muss EVEN rauskommen.

> Mein Verständnisproblem, liegt bei EVEN und ODD. Die Überprüfung auf
> "gerade" oder "ungerade", funktioniert ja wie in der Senderfunktion.


EVEN    <===>  gerade
ODD     <===>  ungerade

sind einfach nur die englischen Ausdrücke dafür.

von Karl H. (kbuchegg)


Lesenswert?

Sei nicht so faul
1
/******************************************************************************/
2
unsigned char send(unsigned char x)
3
{
4
 unsigned char mask=0x01;
5
 unsigned char counter=0;
6
 unsigned char i;
7
8
 for(i=0; i<7; i++)
9
 {
10
  if(x&mask)
11
  {
12
   counter++;
13
  }
14
  mask=mask<<1;
15
 }
16
17
 if(counter%2)
18
 {
19
  x=x|(1<<7);
20
 }
21
 return x;
22
}

trenn dir da den Teil, der die Parity berechnet (und nur die Parity 
berechnet!) in eine eigene Funktion raus und schon drängt sich die 
Lösung für den Empfänger förmlich auf.

von Da Mo (Gast)


Lesenswert?

Wenn ihr wüsstet, wie schwer für mich das Lernen von C ist*g*

DANKE!

von DirkB (Gast)


Lesenswert?

Das hat jetzt aber nichts mit C zu tun.

Das ist in anderen (prozeduralen) Programmiersprachen genau so.
Da kann es aber sein das die Unterscheidung zwischen Zeichen und Zahl 
stärker ist.
Oder das du nicht so einfach an die einzelnen Bits rankommst.

Dafür ist C ein bisschen kryptischer zu schreiben.

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:
> Wenn ihr wüsstet, wie schwer für mich das Lernen von C ist*g*

Das ist schon klar.
Du musst gleichzeitig eine Programmiersprache, Algorithmen und die 
"Taktik des Programmierens" lernen. Und wenn dann die Aufgabenstellung 
etwas realer wird, muss man auch davon etwas verstehen (wer ein Programm 
zum Fliesenlegen schreibt, muss wissen nach welchen Regeln das vor sich 
geht - wie ein Fliesenleger).
Das ist nicht einfach und am Anfang stürzt alles auf dich ein. Aber es 
wird mit der Zeit besser. Neben dem Beherrschen seines Handwerkszeugs 
ist Erfahrung alles.

von Da Mo (Gast)


Lesenswert?

Muss die Sende-Funktion, die um das PARITY - Bit erweiterte Zahl, an die 
Empfangs-Funktion senden oder nur das PARITY - Bit?

von DirkB (Gast)


Lesenswert?

Dominik M. schrieb:
> Muss die Sende-Funktion, die um das PARITY - Bit erweiterte Zahl, an die
> Empfangs-Funktion senden

Ja.

Die Empfangsfunktion muss also die Parity-Information (nach dem 
überprüfen) wieder raus nehmen.

Dominik M. schrieb:
> oder nur das PARITY - Bit
Nur ein Bit zu übertragen gibt zuviel Overhead.
Da würde man eher eine Checksumme bilden und die dann am Schluss 
übertragen.-> CRC

von Da Mo (Gast)


Lesenswert?

Ok! Es muss aber auch noch vereinbart werden, auf was anschließend 
geprüft werden soll (EVEN/ODD) oder? Macht man das mit der 
Präprozessoranweisung   #define, welche global gesetzt wird?

von DirkB (Gast)


Lesenswert?

Wichtig ist, dass Sender und Empfänger die selben Einstellungen 
benutzen.
Ob du das jetzt im Code fest "verdrahtest" oder über #defines machst 
oder über Variabeln einstellbar machst, hängt davon ab, wie viel Aufwand 
du treiben willst.

Die Übermittlung der Einstellungen wird meist in gedruckter Form (auch 
PDF) erledigt.

von Da Mo (Gast)


Lesenswert?

Meine send - Funktion gib den um das Parity erweiterten Wert zurück. 
Wenn ich zum Test, diesen Wert in der main - Funktion mit printf 
ausgeben möchte, bekomme ich nur aa angezeigt. Wenn ich den Wert direkt 
in der send - Funktion ausgebe, funktioniert es. Das heißt, der Fehler 
muss in der Wertrückgabe liegen. Was kann das sein?

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:

> muss in der Wertrückgabe liegen. Was kann das sein?

Du hast einen Fehler in deinem Programm.

Mehr kann man ohne aktuellen Code nicht sagen.

von Da Mo (Gast)


Lesenswert?

Fehler gefunden!!!

Ich hatte die printf Anweisung an der flaschen Position.

von Da Mo (Gast)


Lesenswert?

Sind folgende Anweisungen gleichwertig?

send_data=send_data&(0<<7);

send_data=send_data&~(1<<7);

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:
> Sind folgende Anweisungen gleichwertig?
>
> send_data=send_data&(0<<7);
>
> send_data=send_data&~(1<<7);

Nein.

Versuch mal eine 0 nach links zu verschieben. Was erhältst du?

von Da Mo (Gast)


Lesenswert?

0?

Die zweite Anweisung bedeutet, dass ich das Bit an der Stelle 7 mit 1 
über UND verknüpfe und anschließend negiere oder?

von Da Mo (Gast)


Lesenswert?

Ich möchte euch gerne mein Ergebis zeigen und bitten dieses kurz zu 
überprüfen. Leider habe ich den wirklichen Sinn noch nicht verstanden. 
"data" und "receive_data", müssen bei einer erfolgreichen Übertragen 
ident sein oder? Wenn das nicht der Fall wäre, dann ist ein Fehler bei 
der Übertragung passiert oder?

/* PARITY - Funktion */

#include<stdio.h>

#define EVEN 0
#define ODD 1

unsigned char send(unsigned char);
unsigned char receive(unsigned char);

unsigned char parity;

int main(void)
{
 unsigned char data=0x38; //Eingabe von Uebergabewert
 unsigned char send_data;
 unsigned char receive_data;

 parity=ODD; //Auswahl ob EVEN- oder ODD-Überpruefung

 printf("data: 0x%.2X\n\n",data);
 send_data=send(data);
 printf("send_data: 0x%.2X\n\n",send_data);
 receive_data=receive(send_data);
 printf("receive_data: 0x%.2X\n\n",receive_data);

 system("pause");
 return 0;
}
/*********************************************************************** 
*******/
unsigned char send(unsigned char data)
{
 unsigned char mask=0x01;
 unsigned char counter=0;
 unsigned char i;

 for(i=0; i<7; i++)
 {
  if(data&mask)
  {
   counter++;
  }
  mask=mask <<1;
 }

 if(parity==EVEN)
 {
  if(counter%2)
  {
   data=data|(1<<7);
  }
 }

 if(parity==ODD)
 {
  if((counter%2)==0)
  {
   data=data|(1<<7);
  }
 }

 return data;
}
/*********************************************************************** 
*******/
unsigned char receive(unsigned char send_data)
{
 unsigned char i;
 unsigned char counter=0;
 unsigned char mask=0x01;

 for(i=0; i<8; i++)
 {
  if(send_data&mask)
  {
   counter++;
  }
  mask=mask <<1;
 }

 if(parity==EVEN)
 {
  if(counter%2==0)
  {
   send_data=send_data&~(1<<7);
  }
 }

 if(parity==ODD)
 {
  if(counter%2)
  {
   send_data=send_data&~(1<<7);
  }
 }

 return send_data;
}
/*********************************************************************** 
*******/

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:
> 0?
>
> Die zweite Anweisung bedeutet, dass ich das Bit an der Stelle 7 mit 1
> über UND verknüpfe und anschließend negiere oder?

Reihenfolge!

Das ist nicht das was dort steht. Dort steht:

send_data = send_data & ~(1<<7);

(siehst du, wie ein paar Leerzeichen gleich mal die Lesbarkeit enorm 
verbessern?)

von Da Mo (Gast)


Lesenswert?

Was meinen Sie damit? Was steht nicht dort?

Das mit der Lesbarkeit, werde ich in Zukunft bedenken. Die Leerzeichen 
sind angenehm für das Auge. :-)

von DirkB (Gast)


Lesenswert?

Da steht nicht
Dominik M. schrieb :
> send_data=send_data&~(1<<7); ...
> ... bedeutet, dass ich das Bit an der Stelle 7 mit 1
> über UND verknüpfe und anschließend negiere oder?

Sondern, dass der Wert 1 um 7 Stellen nach links verschoben, negiert und 
anschließend mit send_data UND verknüpft wird.

Die Reihenfolge ist anders.

Dominik M. schrieb:
> Die Leerzeichen
> sind angenehm für das Auge.

Die Leerzeichen hatte ich bei dem Beispiel auch schon drin :)

von Da Mo (Gast)


Lesenswert?

Kann bitte jemand das Programm versuchen und mir Bescheid geben ob die 
Umsetzung richtig ist?

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:
> Kann bitte jemand das Programm versuchen und mir Bescheid geben ob die
> Umsetzung richtig ist?

Du musst auch lernen, wie man selber seinen Code testet.
Probiers doch einfach aus. So viele Bytewerte gibts ja dann auch wieder 
nicht

int main(void)
{
 unsigned char corrected;
 unsigned int  i;

 parity = ODD; //Auswahl ob EVEN- oder ODD-Überpruefung

 for( i = 0; i < 0x100; ++i ) {
   corrected = send( (unsigned char)i );
   printf( "Byte 0x%.2X, nach Parity 0x%.2X\n", i, corrected );
 }

 system("pause");
 return 0;
}

Das haut dir jetzt alle 256 möglichen Bytes durch die Funktion durch und 
erstellt eine Tabelle mit unkorrigiertem Wert und korrigiertem Wert. Und 
die checkst du durch. Wenn da keine Fehler drinnen sind, dann ist deine 
send Funktion korrekt.

von Da Mo (Gast)


Lesenswert?

Danke für den Hinweis aber ich bin leider noch nicht in der Lage für 
solche Spielchen. g

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:
> Danke für den Hinweis aber ich bin leider noch nicht in der Lage für
> solche Spielchen. *g*

Welche Spielchen?
Eine for-Schleife und ein printf?

Dann fehlt es weiter als ich bisher gedacht habe.

von Da Mo (Gast)


Lesenswert?

Die for-Schleife und das printf ist nicht mein Problem.

von Karl H. (kbuchegg)


Lesenswert?

Was dann?

2 stellige Hex-Zahlen auf Binär wandeln? Das geht nach Schema

    0   0000          8   1000
    1   0001          9   1001
    2   0010          A   1010
    3   0011          B   1011
    4   0100          C   1100
    5   0101          D   1101
    6   0110          E   1110
    7   0111          F   1111


Dein Programm wirft zb aus
1
Byte 0x39, nach Parity 0x39

ist das korrekt?

0x39 (das 0x steht für Hex)  hat das Bitmuster  0011 1001
(einfach jede Ziffer in der Tabelle suchen. 3 hat 0011. 9 hat 1001. 
Zusammen haben sie also 0011 1001)

zähle die Einsen, sind 4 Stück.
Eingestellt war ODD Parity, also eine ungerade Anzahl. 4 ist nicht 
ungerade, also ist das falsch. Da hätte das Bitmuster 1011 1001 
rauskommen müssen. In Hex Schreibweise ist das B9. Das Programm hätte 
ausgeben müssen
1
Byte 0x39, nach Parity 0xB9


(ist jetzt nur ein Beispiel)

von Da Mo (Gast)


Lesenswert?

Mein Programm gibt folgendes aus:

data: 0x39 => der zu übergebende Wert

send_data: 0xB9 => 0x39 bekommt parity-Bit an der 7 Stelle, damit eine 
ungerade Anzahl von 1en entsteht (wegen ODD-Vereinbarung)

receive_data: 0x39 => nach dem Senden, wird das parity-Bit wieder 
entfernt

data = receive_data => Übertragung OK!?

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:
> Mein Programm gibt folgendes aus:
>
> data: 0x39 => der zu übergebende Wert
>
> send_data: 0xB9 => 0x39 bekommt parity-Bit an der 7 Stelle, damit eine
> ungerade Anzahl von 1en entsteht (wegen ODD-Vereinbarung)
>
> receive_data: 0x39 => nach dem Senden, wird das parity-Bit wieder
> entfernt
>
> data = receive_data => Übertragung OK!?

na dann passt es doch.

Du bist jetzt in der Beweispflicht, dass dein Prograqmm korrekt ist. Für 
EINEN bestimmten Bytewert hast du das gezeigt. Aber eine Schwalbe macht 
noch keinen Sommer, das wäre zu einfach

      alle ungerade Zahlen sind Primzahlen
      Beweis: 5 ist ungerade und 5 ist prim

      Äääääähm

Deiner Beweispflicht kannst du nachkommen, in dem du entweder
1) zeigen kannst, dass dein Programm aus rein programmiertechnischen
   Überlegungen heraus korrekt sein muss
2) oder aber, in dem du zeigst, dass für alle überhaupt möglichen
   Eingaben immer das richtige Ergebnis rauskommt

Wenn du 1) nicht machen kannst, dann geht bei deinem Programm zumindest 
2). EIn Byte kann 256 mögliche Werte annehmen. Bei dir nur 128, weil ja 
1 Bit für das Parity Bit gebraucht wird. VOn 0 bis 127. Also jagst du 
diese 128 Werte in einer Schleife in deine Funktion rein und siehst 
nach, was jeweils rauskommt. Wenn du für alle Werte zeigst, dass sie 
richtig sind, hast du damit auch gezeigt, dass deine Funktion per 
Definition richtig ist.

von Da Mo (Gast)


Lesenswert?

Wenn man mit dieser Art das parity-Bit setzt, nimmt man es in Kauf, ein 
Bit (Stelle 7) dafür zu verwenden. Habe bis jetzt nur diese Variante 
gelernt.

von Karl H. (kbuchegg)


Lesenswert?

Ja, sagt ja auch keiner was dagegen.
Wenn nur 8 Bit da sind, und eines davon das Parity Bit sein soll, dann 
bleiben nur 7 Nutzbits. Das ist unmittelbar logisch nachvollziehbar.

Aber darum geht es ja auch gar nicht (oder reden wir aneinander vorbei?)
Die Frage ist ja: Dieses Parity Bit - wird das immer korrekt gesetzt 
oder war das nur Zufall, das es in dem einen Beispiel funktioniert hat, 
das du getestet hast?

von Da Mo (Gast)


Lesenswert?

Bei uns liegt ein Verständnisproblem vor. lach


Ich verstehe dieses Programm so: (Beispiel ODD)

Ein Wert soll übermittelt werden; Die send-Funktion überprüft die Anzahl 
der 1en von dem zu übermittelnden Wert; Laut Vereinbarung "ODD", soll 
diese ungerade sein oder werden; Der um das parity-Bit erweiterte Wert, 
wird anschließend in der receive-Funktion wieder von dem parity-Bit 
"befreit"; Wenn der zu übermittelnde Wert "data", dem Wert aus der 
receive-Funktion "receive_Data"entspricht, dann ist die Übermittlung 
korrekt verlaufen;

Man könnte noch eine Fehlermeldung ausgeben, wenn die Übermittlung nicht 
funktioniert hat (z.B. wenn bei der Vereinbarung "ODD" keine ungerade 
Anzahl von 1en in der receive-Funktion ankommt)

Für die Vereinbarung "EVEN" gilt genau das Gegenteil.

von Karl H. (kbuchegg)


Lesenswert?

Dominik M. schrieb:
> Bei uns liegt ein Verständnisproblem vor. *lach*

Seh ich auch so.

Ich stelle ja gar nicht in Frage, dass dein Programm so funktioniert. 
Aber als dein Kunde musst du dir von mir die Frage gefallen lassen: Und 
wie beweisen sie, dass das Programm bei jedem Bytewert die richtige 
Parität einstellt?

Die Frage hast du dir ja auch gestellt:

> und mir Bescheid geben ob die Umsetzung richtig ist?

mit anderen Worten: Ist das Programm korrekt oder nicht.

Das ist jetzt die entscheidende Frage.

von Da Mo (Gast)


Lesenswert?

Das ist genau mein Problem. Ich kann es dem Kunden nicht beweisen. :-(

von DirkB (Gast)


Lesenswert?

Für 128 Werte kannst du es.
- Druck die 128 Werte wie beschrieben aus.
- Schreib die Hex->Bin Tabelle darunter.

Und vergleiche "per Hand" und mit deinem Kopf.

Das kann der Kunde auch selber überprüfen wenn er es nicht glaubt.

von Da Mo (Gast)


Lesenswert?

Ich habe jetzt mein Programm über eine for-Schleife mit 128 Werten 
gefüttert (0x00 bis 0x7F).

Jetzt kann ich das Verhalten bei EVEN oder ODD testen.

/* PARITY - Funktion */

#include<stdio.h>

#define EVEN 0
#define ODD 1

unsigned char send(unsigned char);
unsigned char receive(unsigned char);

unsigned char parity;

int main(void)
{
 unsigned char i;
 unsigned char data;
 unsigned char send_data;
 unsigned char receive_data;
 unsigned char counter=0;

 printf("**************************************************************** 
\n");
 printf("* data = zu uebergebender Wert 
*\n");
 printf("* send_data = Wert um parity-Bit erweitert, wenn notwendig 
*\n");
 printf("* receive_data = empfangener Wert ohne parity-Bit 
*\n");
 printf("* Uebertragung erfolgreich, wenn data = receive_data 
*\n");
 printf("**************************************************************** 
\n\n");

 printf("**************************TESTLAUF****************************** 
\n\n");

 for(i=0x00; i<0x80; i++)
 {
  data = i;

  parity=EVEN; //Auswahl ob EVEN- oder ODD-Überpruefung

  send_data=send(data);

  receive_data=receive(send_data);

  printf("data: 0x%.2X; send_data: 0x%.2X; receive_data: 0x%.2X\n\n", 
data, send_data, receive_data);

  counter++;
 }

 printf("counter: %d\n\n", counter);

 system("pause");
 return 0;
}
/*********************************************************************** 
*******/
unsigned char send(unsigned char data)
{
 unsigned char mask=0x01;
 unsigned char counter=0;
 unsigned char i;

 for(i=0; i<7; i++)
 {
  if(data&mask)
  {
   counter++;
  }
  mask=mask <<1;
 }

 if(parity==EVEN)
 {
  if(counter%2)
  {
   data=data|(1<<7);
  }
 }

 if(parity==ODD)
 {
  if((counter%2)==0)
  {
   data=data|(1<<7);
  }
 }

 return data;
}
/*********************************************************************** 
*******/
unsigned char receive(unsigned char send_data)
{
 unsigned char i;
 unsigned char counter=0;
 unsigned char mask=0x01;

 for(i=0; i<8; i++)
 {
  if(send_data&mask)
  {
   counter++;
  }
  mask=mask <<1;
 }

 if(parity==EVEN)
 {
  if(counter%2==0)
  {
   send_data=send_data&~(1<<7);
  }
 }

 if(parity==ODD)
 {
  if(counter%2)
  {
   send_data=send_data&~(1<<7);
  }
 }

 return send_data;
}
/*********************************************************************** 
*******/

von Da Mo (Gast)


Lesenswert?

Was wäre die einfachste Möglichkeit, eine fehlerhafte Übertragung zu 
melden?

von DirkB (Gast)


Lesenswert?

An wen melden?

Globale Variable myerrno setzen.

unsigned char receive(unsigned char send_data, int *error);

Ausgabe auf stderr: fprintf(stderr, "Parity Error\n");

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.