Überprüfen ob Eingabe binär ist



  • Hallo,

    ich habe folgende Aufgabe bekommen:

    "In der Variable bzahl wird eine Zahl eingelesen. Prüfen Sie, ob dies eine Binärzahl bestehend aus 0 und 1 ist und belegen Sie die Variable ist_bzahl entsprechend, d.h. true, wenn es sich um eine Binärzahl handelt, ansonsten false."

    Dieser Quelltext ist bereits vorgegeben:

    #include <stdio.h>
    
    int main() {
        int bzahl;
        scanf("%i", &bzahl);
    
        bool ist_bzahl;
        // Hier ihr Programmcode:
    
        printf("%i", ist_bzahl);
    }
    

    Ich habe schon einiges recherchiert, komme aber zu keinem Ergebnis.
    Wir haben aktuell nur Schleifen besprochen. Was heißt, dass eine Lösung mit Arrays ausgeschlossen ist.

    Bitte im Hilfe bei der Lösung meines Problems.

    Grüße
    Tr0ubleGum



  • Hast Du eine Idee, wie Du an die letzte Stelle der Zahl im 10er-System kommen könntest? An die zweitletzte? Und dann an die drittletzte? Dann könntest Du nämlich einfach immer prüfen ob das ne 0 oder ne 1 ist, und wenn das mal nicht der Fall ist, dann solltest Du false in Deine Variable reinschreiben.



  • Ja, ich hatte da an eine Lösung mit % gedacht, wobei der Rest immer 0 oder 1 betragen muss.
    Nur leider fällt mir die praktische Umsetzung schwer.

    while(bzahl!=0){
            if(bzahl%10==(0||1)){
                printf("%i ", bzahl);
                ist_bzahl=true;
                bzahl/=10;
            }else{
                ist_bzahl=false;
            }
        }
    

    An etwas in der Art habe ich gedacht, nur leider gibt es immer nur ein Timeout.



  • Jester schrieb:

    ..

    Aber 1000 Euro Preisgeld kann man für die (gute) Antwort noch nicht geben 😉
    @TO
    Versuche mal die einzelnen Befehle sinnvoller zu staffeln und ob ein do loop hier besser funktioniert.



  • Habe das Ganze zu einer for-Schleife umgewandelt:

    for(int i=10; bzahl%i==(0||1); i*=10){
            if(bzahl%i==(0||1)){
                bzahl/=10;
                printf("%i\n",bzahl);
                ist_bzahl=true;
            }else{
                ist_bzahl=false;
            }
        }
    

    Problem ist jetzt, dass aus der for-Schleife gesprungen wird, sobald eine "0" kommt.

    Kann mir jemand vielleicht entgegenkommen und mir einen kleinen Ansatz geben?



  • Ohne auf den Algorithmus zu gucken:

    bzahl%i==(0||1)
    

    Huh? Großer Käse. Du willst vermutlich schreiben "wenn bzahl%i eine 0 oder eine 1 liefert", aber das geht so nicht.

    (bzahl%i==0 || bzahl%i==1)
    


  • Ich habe jetzt noch ein wenig was ausprobiert.

    Wenn ich die Zahl trennen kann mit:

    while(bzahl){
                printf("%i ", bzahl%10);   //Nur zu Kontrolle
                bzahl/=10;
        }
    

    Warum funktioniert dann folgendes nicht?

    while(bzahl){
                printf("%i ", bzahl%10);
            if(bzahl%10==0 || bzahl%10==1){
                ist_bzahl=true;
            }else{
                ist_bzahl=false;
            }
                bzahl/=10;
        }
    

    Als Beispiele gebe 11001101, 120011, 1 und 2 ein.
    Für alle Fälle außer 120011 funktiert mein Quellcode.


  • Mod

    Deine Testprozedur lässt arg zu wünschen übrig, wenn du nur diese 4 Fälle testest und das für ausreichend hältst. Probier mal beliebige Zahlen aus, die mit 1 beginnen. Das Ergebnis sollte dir einen starken Hinweis auf deinen Fehler geben.



  • if(bzahl%10 > 1)
    

    Das einzubauen kriegst du schon hin...



  • Im Zweifel gib dir mal jede Stelle einzeln auf dem Bildschirm aus und dazu was Dein Algorithmus gerade darüber denkt ob die Eingabe eine Binärzahl ist oder nicht. Teste dann damit die Zahl 120120120.



  • Ich verstehe zwar wo der Fehler liegt, aber mir fällt absolut keine Lösung ein.

    Für folgendes erhalte ich das richtige Ergebnis für alle Zahlen die nicht binär sind:

    do{
            if(bzahl%10==0 || bzahl%10==1){
                bzahl/=10;
                ist_bzahl=true;
            }else{
                ist_bzahl=false;
            }
        }while(ist_bzahl==true);
    

    Und für das hier, erhalte ich das richtige Ergebnis für alle Zahlen die binär sind:

    do{
            if(bzahl%10==0 || bzahl%10==1){
                bzahl/=10;
                ist_bzahl=true;
            }else{
                ist_bzahl=false;
            }
        }while(bzahl);
    

    Ich verzweifle echt an dieser warscheinlich richtig einfachen Aufgabe..

    Danke aber schon mal für die vielen Tipps.



  • Check mal die Schleifenbedingung.



  • Danke nochmal an alle die mir geholfen haben.

    Schlussendlich habe ich ein Ergebnis, dass die Aufgabenstellung erfüllt:

    #include <stdio.h>
    
    int main() {
        int bzahl;
        scanf("%i", &bzahl);
    
        bool ist_bzahl;
        // Hier ihr Programmcode:
        do{
            if(bzahl%10==0 || bzahl%10==1){
                bzahl/=10;
                ist_bzahl=true;
            }else{
                ist_bzahl=false;
            }
        }while(bzahl && ist_bzahl==true);
    
        printf("%i", ist_bzahl);
    }
    

    Grüße
    Tr0ubleGum



  • int bzahl = 120120120;
    bool ist_bzahl = true;
    while(bzahl)
    {
    	printf("%i ", bzahl%10);
    	if(bzahl%10 > 1)
    	{
    		ist_bzahl=false;
    		break;
    	}
    	bzahl/=10;
    }
    printf("%s", ist_bzahl ? "bin" : "nicht bin" );
    

    Und noch etwas knackiger:

    int bzahl = 120120120;
    bool ist_bzahl = true;
    while(bzahl && ist_bzahl)
    {
    	printf("%i ", bzahl%10);
    	ist_bzahl = bzahl % 10 <= 1;
    	bzahl/=10;
    }
    printf("%sbin", ist_bzahl ? "" : "nicht " );
    


  • schrittweise optimierung, toll 👍 ( 😋 )
    (haskell-)

    Prelude> reverse "1234"
    "4321"
    Prelude>
    


  • nachtfeuer schrieb:

    schrittweise optimierung, toll

    Und auch noch betrunken um halb fünf morgens...

    Ist eigentlich auch nur einer meiner von rapso reklamierten Einzeilern. 😉



  • @OP: schau dir den Trick von EOP gut an. Er setzt den Wert der Entscheidungsvariable am Anfang einmal auf true und wenn eine nicht-binäre stelle auftaucht, dann setzt er sie auf false. Es kann ihm daher gar nicht passieren, dass er aus versehen wieder von false auf true zurück stellt. Sowas in der Art wirst Du, sofern Du weiterhin mit Programmierung zu tun hast, noch häufig brauchen.



  • Ist ja eigentlich nicht wirklich ein Trick.
    tricky ist nur die geschickte Ausnutzung der Operatorenrangfolge im Schleifenkörper.



  • EOP schrieb:

    Ist ja eigentlich nicht wirklich ein Trick.

    Stimmt, wenn es mehr als einmal funktioniert, ist es eine Technik. 😉
    Und zwar offensichtlich eine, die dem OP fehlt.


Log in to reply