Duale Eingabe in C-Programm



  • Was stört dich an einem String? Den kannst du ganz bequem von man: strtol in die richtige Zahl umwandeln lassen, dann musst du dir nur noch über die Ausgabe Gedanken machen.
    🙂



  • Was hälst du denn von sowas:

    int hoch(int x, int y){ //rechnet x hoch y
        int r;
        for(r=1; y>0; y--) r*=x;
        return r;
    }
    
    int bin(int x){ //rechnet Binärzahl in dezimaler Darstellung in Binärzahl um
        int r = 0;
        for(int stelle = 0; stelle<11; stelle++) //funktioniert nur mit 32Bit ints
            if (hoch(10, stelle) && x) r+=hoch(2, stelle);
        return r;
    }
    


  • knivil schrieb:

    doch das möchte ich erhrlich gesagt nicht.

    ... und begruendest es mit Lernfaulheit. Aber ich glaube, dir wird nichts anderes ueberig bleiben.

    Tut mir leid wenn du diesen eindruck hast, das hat nichts mit Lernfaulheit zu tun.
    Ich bin nur am überlegen was am effjektivsten ist. Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht. Ich könnte das ganze sicherlich auch über einen String Array machen, nur dann wäre der Quellcode um einiges größer als wenn ich es über ein Integer-Array machen könnte.

    Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.



  • Was ist denn heute nur los?

    char binstr[SIZE];
    fgets(binstr, SIZE, stdin);
    long zahl1 = strtol(binstr, NULL, 2);
    // wenn du das nochmal mit einem 'long zahl2' machst, dann geht das XOR so:
    long xored = zahl1 ^ zahl2;
    

    Wenn du statt NULL noch die Adresse eines char-Zeigers mitgibst, kannst du auch noch alle möglichen Fehler abfangen.

    Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.

    War das nicht kurz genug? Btw: was hat denn die Codegrösse mit der Laufzeit zu tun?
    🙂



  • damit das Programm schnell und platzsparend abläuft

    Und dann holst du so ein Monster wie scanf() an Bord?
    😕



  • µngbd schrieb:

    damit das Programm schnell und platzsparend abläuft

    Und dann holst du so ein Monster wie scanf() an Bord?
    😕

    Würde mich auf eine Erklärung freuen...
    Wie ist mit 'Monster' gemeint?



  • Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht.

    Dann nimm eine andere Sprache, C++ oder Java oder Haskell oder ... bieten sich an.

    Als Alternative von scanf bietet sich vielleicht die Moeglichkeit an, deine Binaerzahlen als String per Kommandozeilenargument einzugeben. Die Umwandlung erfolgt dann von hinten nach vorne, indem entweder eine 1 oder 0 (abhaengig vom char-Wert "1" oder "0") geshiftet wird. Oder du verwendest das schon angesprochene strol().



  • sunny31 schrieb:

    µngbd schrieb:

    Und dann holst du so ein Monster wie scanf() an Bord?
    😕

    Würde mich auf eine Eklärung freuen...
    Wie ist 'Monster' gemeint?

    Naja, scnaf() muss die ganze Logik irgendwo bereitstellen, um die Formatstring-Syntax zu verstehen. Wenn Speicher und Laufzeit knapp sind, könnte es sich schon mal auszahlen, scanf(), printf() und ihre Brüder ganz raus zu nehmen. Die gehören sicher zu den aufwändigsten Funktionen in der ganzen Standard-Bibliothek.

    Mir fällt das immer wieder ein, wenn ich sowas sehe:

    char c;
    scanf("%c", &c);    // statt getchar()
    // oder
    char s[SIZE];
    scanf("%s ", s);    // statt fgets()
    

    Das ist natürlich Wahnsinn. Zahlen einlesen ist ja noch in Ordnung, aber die Standard-Formatstrings können eben keine Binärdarstellungen, obwohl manche Compiler %b (für Binärdarstellungen) kennen. Dafür gibt es im Standard aber strtol().
    🙂



  • Chris12 schrieb:

    Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.

    dann mach dir doch 'ne funktion, die einen string aus nullen und einsen in eine zahl umwandeln kann, ist nicht mehr als ein drei- oder vierzeiler.

    knivil schrieb:

    Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht.

    Dann nimm eine andere Sprache, C++ oder Java oder Haskell oder ... bieten sich an.

    ich weiss ja nicht, ob haskell schnellen, kleinen maschinencode erzeugen kann, aber Java z.b. braucht im normalfall eine virtual machine o.ä. und c++ ...ähm, *räusper*
    🙂



  • fricky schrieb:

    ich weiss ja nicht, ob haskell schnellen, kleinen maschinencode erzeugen kann

    Glaub ich nicht. Das Ding ist lazy. Im besten Fall kommt wahrscheinlich immer noch eine riesige Runtime-Bib. dazu (ausser man baut alles aus den Axiomen zusammen, aber das ist wiederum eine epische Laufzeitverschwendung). Und den Compiler verstehen dann sicher nur mehr drei Leute auf der Welt.

    fricky schrieb:

    und c++ ...ähm, *räusper*

    C++ hat sicher irgendeinen Zauberspruch, den man zwischen cin und die Variable schreiben muss, damit die Zahl zur Basis 17 genommen wird. Fragt dann wahrscheinlich insgeheim bei strtol() nach, weil Zaubern gar nicht so einfach ist, und deshalb von einem Magier geerbt werden muss.
    🙂



  • Ok erstmal Danke für die nette Diskussion.
    Die anregungen haben mir geholfen mein Problem zu lösen.

    Leider darf ich keine andere Sprache als C nehmen. Da ich momentan im 1.Semester nur ANSI C behandele.

    Bisher haben wir da irgendwie überwiegend mit scanf gearbeitet, deshalb habe ich es benutzt. Ich poste mal meine bisherige Lösung, das Programm ist noch nicht fertig aber bin damit als ersten Zwischenschritt zufrieden.

    Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define BUF 255
    
    char HammingDistance(char Code[],char Code2[])
    {
    	int array_groese,Hamming;
    	char i;
    	char v[80]={' '};
    
        array_groese =0;
    	Hamming =0;
    
    	while (Code[array_groese]!='\0'){array_groese++;}//Größe des String-Arrays bestimmen
    	for (i=0;i<=array_groese-1;i++){if ((Code[i]^Code2[i])==1){Hamming=Hamming+1;}}
    	printf("Haben die Hamming Distance : %d\n",Hamming);
    	printf("\n");
    
    	return(Hamming);
    }
    
    void Sort(int value[],int CodewörterAnzahl)
    {
       int i,j;
       char buf[BUF];
       char buf2[BUF];
    
       //Vergleicht alle Codewörter mit einander
       for(i=0;i<=CodewörterAnzahl-1;i++)
       {
    	   for(j=(i+1);j<=CodewörterAnzahl-1;j++)
    	   {
    		   itoa(value[i], buf, 10);
    		   itoa(value[j], buf, 10);
    		   printf("Codewort %d & Codewort %d\n",value[i],value[j]);
    		   HammingDistance(itoa(value[i], buf, 10),itoa(value[j], buf2, 10));
    	   }
       }
    }
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(void) {
       int *value;
       int size, i = 0;
       printf("Wie viele Werte benötigen Sie : ");
       scanf("%d", &size);
       value = (int *)malloc(size*sizeof(int));
       if( NULL == value ) {
          printf("Fehler bei malloc....\n");
          return EXIT_FAILURE;
       }
       while( i < size ) {
          printf("Wert für value[%d] eingeben : ", i);
          scanf("%d", &value[i]);
          i++;
       }
       printf("Hier Ihre Werte\n");
       for(i=0; i < size; i++){
    	   printf("value[%d] = %d\n", i, value[i]);}
    
       Sort(value,size);
    
       return EXIT_SUCCESS;
    }
    


  • Ich habe jetzt nur noch ein Problem:
    Wenn ich 0100 eingeben wird an die Funktion 100 übergeben was mir auch logisch erscheint. Wie könnte ich die führende 0 erhalten?



  • µngbd schrieb:

    ... ... ...

    Wie immer bin ich dir dankbar für deine Erklärungen. :xmas1:



  • Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    Warum nicht int 's (oder sowas) für die Zahlen nehmen und das XOR den Prozessor in einem Schritt machen lassen? Dann könntest du dir den ganzen itoa()-Wahnsinn sparen. Der ist nämlich echt völlig unnötig.
    🙂



  • µngbd schrieb:

    Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    Warum nicht int 's (oder sowas) für die Zahlen nehmen und das XOR den Prozessor in einem Schritt machen lassen? Dann könntest du dir den ganzen itoa()-Wahnsinn sparen. Der ist nämlich echt völlig unnötig.
    🙂

    Meinst du in der Hamming Funktion ?
    Wenn ja habe ich das deshalb gemacht das ich die 1 aus dem XOR Produkt zählen kann.

    Als Bsp.: Wenn ich die Zahlen 1010 und 1111 als int übergeben würde und diese XOR Verknüpfe bekäme ich als Return ja ne 5 (Binär 101). Da wüsste ich jetzt nicht wie ich die 1 zählen kann. Dann müsste ich ja erst wieder die 5 in ne Dualzahl mittels ner Funktion umwandeln, diese in einem String speichern und dann die Anzahl von 1en Zählen.

    Deshalb dachte ich mir das ich die String umwandlung gleich am Anfang vornehme.

    Nur habe ich immer noch das Problem mit der führenden 0, die dann ja abgesägt wird.



  • µngbd schrieb:

    ausser man baut alles aus den Axiomen zusammen, aber das ist wiederum eine epische Laufzeitverschwendung

    es gibt eine programmiersprache, die mit 'axiomen' arbeitet? wie geht das? oder bedeutet der begriff da was anderes?

    µngbd schrieb:

    C++ hat sicher irgendeinen Zauberspruch, den man zwischen cin und die Variable schreiben muss, damit die Zahl zur Basis 17 genommen wird. Fragt dann wahrscheinlich insgeheim bei strtol() nach, weil Zaubern gar nicht so einfach ist, und deshalb von einem Magier geerbt werden muss.

    in c++ macht man sowas mit templates, dabei rechnet der compiler die werte für alle möglichen bitmuster eines 'unsigned' im voraus aus und speichert sie in einem 4GB array *fg*

    Chris12 schrieb:

    Leider darf ich keine andere Sprache als C nehmen. Da ich momentan im 1.Semester nur ANSI C behandele.

    C ist schon ok, für low-leveliges bitgewurschtel gibt es kaum besseres.

    Chris12 schrieb:

    Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    deine hammingdistanz-funktion sieht seltsam aus. wenn sie mit strings arbeiten soll (und es sieht so aus), dann hat das XOR dort doch nichts verloren. vorschlag (ungetestet):

    // geht davon aus, dass beide strings gleich lang sind
    int HammingDistance (char Code[],char Code2[])
    {
        int Hamming;
        for (Hamming=0; *Code; Code++, Code2++)
            if (*Code != *Code2)
                Hamming++;
        return Hamming;
    }
    

    Chris12 schrieb:

    Wenn ich 0100 eingeben wird an die Funktion 100 übergeben was mir auch logisch erscheint. Wie könnte ich die führende 0 erhalten

    bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
    🙂



  • fricky schrieb:

    deine hammingdistanz-funktion sieht seltsam aus. wenn sie mit strings arbeiten soll (und es sieht so aus), dann hat das XOR dort doch nichts verloren. vorschlag (ungetestet):

    // geht davon aus, dass beide strings gleich lang sind
    int HammingDistance (char Code[],char Code2[])
    {
        int Hamming;
        for (Hamming=0; *Code; Code++, Code2++)
            if (*Code != *Code2)
                Hamming++;
        return Hamming;
    }
    

    Wenn ich das richtig erkenne würde dann allerdings deine Funktion nur überprüfen ob die beiden Codewörter unterschidlich sind. Ich muss allerdings die enthaltenen 1 aus dem XOR Produkt der beiden Codwörter zählen.

    fricky schrieb:

    bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
    🙂

    Ich brauche die aber nicht bei der Ausgabe sondern bei der Übergabe an die Hamming Distance.

    Bsp.:

    0101
    1111
    ----
    1010 Hamming Distance von 2

    Da der Rechner aber die 0 abschneidet kommt das raus:
    101
    1111
    ----
    010 HD von 1



  • Ok hab gerade deine Funktion getestet, die funktioniert einwandfrei, ich verstehe allerdings nicht wieso.



  • fricky schrieb:

    es gibt eine programmiersprache, die mit 'axiomen' arbeitet? wie geht das? oder bedeutet der begriff da was anderes?

    Das ist ein lustiger Sport in funktionalen Sprachen, nämlich möglichst alle Funktionen durch andere definieren, und zwar solange, bis nur mehr eine Handvoll überbleibt. Die werden dann gerne Axiome ganannt, wahrscheinlich um damit anzugeben, dass es nur so wenige sind. Mit Sprachen die nur bei Bedarf auswerten, geht das echt wunderbar, weil zB ein if eine ganz normale Funktion sein kann.

    Chris12 schrieb:

    Wenn ja habe ich das deshalb gemacht das ich die 1 aus dem XOR Produkt zählen kann.

    Aber eine Lösung für int's zu finden, wäre nicht wirklich schwer gewesen:
    http://en.wikipedia.org/wiki/Hamming_distance#Algorithm_example
    🙂



  • Chris12 schrieb:

    Wenn ich das richtig erkenne würde dann allerdings deine Funktion nur überprüfen ob die beiden Codewörter unterschidlich sind. Ich muss allerdings die enthaltenen 1 aus dem XOR Produkt der beiden Codwörter zählen.

    XOR kannst nehmen, wenn die codewörter binär vorliegen (die summe der 1-bits ist dann die hamming-distanz). aber wenn du strings (0 und 1 als ascii-zeichen) verwendest, dann musste eigentlich nur die unterschiede zählen.

    Chris12 schrieb:

    fricky schrieb:

    bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
    🙂

    Ich brauche die aber nicht bei der Ausgabe sondern bei der Übergabe an die Hamming Distance.

    klar, dafür müssen die strings gleich lang sein. also, den kürzeren vorn mit nullen auffüllen, bis er so lang ist, wie der längere.

    Chris12 schrieb:

    Ok hab gerade deine Funktion getestet, die funktioniert einwandfrei, ich verstehe allerdings nicht wieso.

    na, die zählt einfach nur ungleiche zeichen. so ist doch die hamming-distanz definiert, oder verwechsle ich das jetzt mit irgendwas?
    🙂


Anmelden zum Antworten