komische fehler !(1) = 1



  • etlam schrieb:

    Jetzt habe ich nichts geändert und das ganze auf mit einer anderen Live-Cd probiert - da ging es auf einmal - und das komischste ist, dass es dort wo es vorher nicht ging jetzt auf einmal auch geht!

    etlam

    Hört sich für mich so an, als wäre da eine temporäre Datei benutzt worden die nicht mehr auf dem aktuellsten Stand war.
    Falls du mal wieder sowas hast, dann lösch alle temporäre Dateien und mach ein komplettes Rebuild.



  • Alsomein Programm selber benutzt keine Temporänen Dateien, und ich benutzKnoppix, und auch wenn ich nach dem starten direkt es versucht hatte, ging es nicht.
    Jetzt geht es, aber nur wenn ich am ende der schleife soetwas mache:

    if(a>b)
    {
    ;
    }
    

    Komisch, oder?

    etlam



  • Es handelt sich bei rol doch um einen von Dir selbst geschriebenen Datentyp, oder? Hast Du schonmal daran gedacht, dass Dein operator< einfach kaputt sein könnte?



  • Ich meinte die temporären Dateien die dein Kompiler erstellt, die erstellt er damit er nicht jedes mal das gesamte Projekt neu übersetzen muss.

    Zeig mal den Code für deinen op> (also für die aktuelle Version mit der dieses Problem auftritt).

    Und hast du mal folgendes versucht:

    for( int i = 0; i < 20; ++i )
      cout << ( a > b ) << "\n";
    

    Würde mich mal interressieren ob da immer das gleiche herauskommt, falls nicht ist dein op> auf jeden Fall fehlerhaft.



  • Also wegen temporänen Dateien: Ich benutz z.Z. Knoppix, da ist nix mit temporänen Dateien, wenn ich neu starte, da Knoppix ja eine Live-Cd Distribution ist.
    Der Operator > funktioniert.
    Ich habe mir das ganze auch oft ausgeben lassen, wie vorgeschlagen, und es kommt immer das richtige Ergebnis raus, nur im while() und if() wird die Rückgabe falsch interpretiert oder umgewandelt oder so.

    etlam



  • etlam schrieb:

    Also:
    bevor der ganze Rest anfängt, habe ich zwei Variablen genommen, ihnen genau die selben Werte gegeben und genau gleich ausgegeben:
    +0>+0.001 : 0
    heißt es da.

    Wenn du ihnen genau die selben Werte gegeben hast, ist doch arg verwunderlich, dass da einmal "0" und einmal "0.001" steht.
    Vielleicht postest du mal kurz die relevanten Teile deiner Klassendefinition.



  • Kann natürlich auch sein, dass du dir irgendwo den Stack oder den Heap zerschossen hast. Es sollte mich jedenfalls arg wundern wenn da der GCC einen Fehler gemacht hätte. Übersetz das Programm mal mit verschiedenen Optionen (-O0 -O1 -O2 -O3 -Os -g -p) wenn sich das Programm verschieden verhält dann ist das dein Fehler.



  • pumuckl schrieb:

    etlam schrieb:

    Also:
    bevor der ganze Rest anfängt, habe ich zwei Variablen genommen, ihnen genau die selben Werte gegeben und genau gleich ausgegeben:
    +0>+0.001 : 0
    heißt es da.

    Wenn du ihnen genau die selben Werte gegeben hast, ist doch arg verwunderlich, dass da einmal "0" und einmal "0.001" steht.
    Vielleicht postest du mal kurz die relevanten Teile deiner Klassendefinition.

    Also mit dieselben Werte meine ich natürlich die selben Werte, wie sie hinterher in der Schleife vorkommen!

    Das mit den verschiedenen Optionen werde ich morgen ausprobieren, Vielen Dank für den Hinweis.

    etlam



  • Sag mal, schämst du dich für deinen Code? Nun zeig' ihn doch endlich her!



  • Das ist der Code für den Operator >:

    bool& operator>(rol& a, rol& b)
    {
    	bool aistbruch=0;
    	bool bistbruch=0;
    	int awo = 0;
    	int bwo = 0;
    	int asize = a.wert.size();
    	int bsize = b.wert.size();
    	while(awo != asize)
    	{
    		if(a.wert[awo]=='|')
    		{
    			aistbruch=1;
    		}
    		awo++;
    	}
    	while(bwo != bsize)
    	{
    		if(b.wert[bwo]=='|')
    		{
    			bistbruch=1;
    		}
    		bwo++;
    	}
    	static bool reuckgabe;
    	if((aistbruch==1)||(bistbruch==1))
    	{
    		if(aistbruch==0)
    		{
    			a.wert = bbeideszubruch(a.wert);
    		}
    		if(bistbruch==0)
    		{
    			b.wert = bbeideszubruch(b.wert);
    		}
    		a.wert = vmachevorzeichen(a.wert);
    		b.wert = vmachevorzeichen(b.wert);
    		reuckgabe = vbistgroesser(a.wert,b.wert);
    	}
    	else
    	{
    		a.wert = vmachevorzeichen(a.wert);
    		b.wert = vmachevorzeichen(b.wert);
    		reuckgabe = vistgroesser(a.wert,b.wert);
    	}
    	return(reuckgabe);
    }
    

    Vielen Dank schonmal im voraus,
    etlam



  • Au Backe. Du machst Zuweisungen an a.wert und b.wert. Da aber a und b Referenzen auf zwei rols sind, veraenderst du im Endeffekt die beiden Parameter, die du uebergibst. Egal wie klein der Effekt sein mag, operator< mit Seiteneffekten auf die Operanden ist alles andere als das, was man erwarten darf. Des weiteren kann dein operator< nicht fuer const rol aufgerufen werden. Du solltest da evtl. noch einiges am Design veraendern.

    Ausserdem:
    - wenn du bools benutzt, solltest du auch true und false benutzen an Stelle von 0 und 1; Liest sich leichter.
    - deine while Schleife laeuft weiter, auch wenn bereits ein '|' gefunden wurde. Pack da doch entweder ein break in die Schleife oder ein "&& !aistbruch" zur Bedingung dazu. Kann enorm Zeit sparen, wenn dein rol.wert so elend lang sein kann wie deine Signatur vermuten laesst.
    - der vergleich von einem bool mit 1 ist doppelt gemoppelt. Es reicht ein

    if (aistbruch || bistbruch)
    

    - deine variable rueckgabe ist unnoetigerweise static. Sie wird angelegt und bleibt bestehen, auch wenn weit und breit kein operator< zu sehen ist. Und da du keine Informationen von einem Aufruf zum naechsten transportieren willst, macht static hier keinen Sinn.
    - auch nonstatic waere rueckgabe einen unnoetige variable. statt der zuweisung und dem anschliessenden return kannst du auch jeweils einfach folgendes schreiben:

    return vbistgroesser(a.wert,b.wert);
    

    Wenn du uns jetzt noch ein paar Details z.B. ueber die Art der Speicherung deiner Werte in den rols erzaehlst udn uns evtl auch noch die Implementierung von "bbeideszubruch" etc. zeigst, kann man dir vielleicht sogar helfen, indem wir dir einen kuerzeren operator< ohne Seiteneffekte erstellen helfen. 🙂



  • O.K.
    Also:
    Es gibt ja die Klasse rol, in der sind die Operatoren als "friends" deklariert.
    darin gibt es einen vector <char> wert , in dem die Zahl gespeichert ist.
    vector<char> bbeideszubruch(vector <char> x)
    gibt die selbe Zahl zurück, aber als Bruch - eigentlich ganz simpel, ist auch gut getestet, das sollte eigentlich machen was es soll.
    vmachevorzeichen sieht vom Aufbau her fast genauso aus, macht eben ein Vorzeichen vor die Zahl, falls diese noch keines hat.

    Das mit dem, dass die Operanden verändert werden ist durchaus gewünscht.
    Denn angenommen man hat eine irre lange Zahl (die sich selten ändert), die man in einer Schleife ganz oft mit verschiedenen anderen Zahlen vergleicht, addiert, wwas auch immer.

    Dann müsste man (würde man diesen Operanden nicht dort ändern), diese Zahl jedes Mal umwandeln (Und z.B. das Bruch kürzen dauert ganz schön lange!).
    Da ist es insgesamt also schneller diese Zahl einmal umzuwandeln und danach nicht mehr.

    Das mit dem nicht abbrechen bei | ist ja ein dummer Fehler von mir... 🙄, vielen Dank für den Hinweis.

    Vielen Dank schonmal im voraus,
    etlam



  • Wenn du der Meinung bist, eine Zahl ist zu lang, dann solltest du sie gleich bei der Erzeugung auf ein erträgliches Maß kürzen (und du solltest auch alle Werte gleich als Bruch speichern - ganze Zahlen mit Nenner 1) 😉 Mit deinem Operator hast du auf jeden Fall das Problem, daß er nur mit benannten Operatoren aufgerufen werden kann - ein if(a>b+c)... wird der Compiler nicht akzeptieren.

    PS: Und wie ist der vector<char> eigentlich aufgebaut?



  • CStoll schrieb:

    Mit deinem Operator hast du auf jeden Fall das Problem, daß er nur mit benannten Operatoren aufgerufen werden kann - ein if(a>b+c)... wird der Compiler nicht akzeptieren.

    Tut mir Leid, aber ich habe von "benannten Operatoren" noch nie was gehört, was bedeutet das?
    Also in vector<char> wert ist das so (bei z.B. 35.4):
    wert[0] --> 3
    wert[1] --> 5
    wert[2] --> .
    wert[3] --> 4
    Einfach alles nacheinander, eindimensional.

    Vielen Dank schonmal im voraus,
    etlam



  • Sorry, ich meinte "benannte Operanden" (aka Variablen) - im Ausdruck 'a>b' vergleichst du zwei Variablen, bei 'a>b+c' vergleichst du eine Variable mit einem temporären Wert (der Rückgabewert von op+) - das geht nur, wenn dein Vergleichsoperator seine Parameter per Kopie oder konstante Referenz entgegennehmen würde.

    etlam schrieb:

    Also in vector<char> wert ist das so (bei z.B. 35.4):
    wert[0] --> 3
    wert[1] --> 5
    wert[2] --> .
    wert[3] --> 4
    Einfach alles nacheinander, eindimensional.

    Also einfach die Zahl in Textversion? Da solltest du dir mal einen einheitlicheren Aufbau für deine Zahlen überlegen, das erleichtert auch das Rechnen, weil du keine Fallunterscheidungen beachten mußt.


Anmelden zum Antworten