The Daily WTF



  • Sovok schrieb:

    int makeNegative( int n )
    {
      return -n;
    }
    

    Ein schönes Beispiel für übermässiges Refactoring.

    Um richtig zu machen müsste man noch auf 0 testen 😃

    int makeNegative( int n )
    {
      int num = 0;
      if (n<0) num = abs(n);
      else {
        if (n>0) num = ( 0 - 1 ) * abs(n);
        else {
          if (n == 0) num = 0;
        }
      }
      return num;
    }
    


  • IF (current_num - prev_num = current_num) THEN
    

    Was soll daran schlecht sein? Wenn es um floats geht, ist das eine nette Methode rauszufinden, ob "prev_num" im Vergleich zu "current_num" nicht etwas gar klein ist 😉



  • JBeni schrieb:

    IF (current_num - prev_num = current_num) THEN
    

    Was soll daran schlecht sein? Wenn es um floats geht, ist das eine nette Methode rauszufinden, ob "prev_num" im Vergleich zu "current_num" nicht etwas gar klein ist 😉

    irre ich mich oder kann man den code ersetzen durch

    if ( prev_num == 0 ) ...
    


  • JBeni schrieb:

    Was soll daran schlecht sein?

    Weil man dann gleich prüfen kann, ob prev_num gleich 0 ist.

    JBeni schrieb:

    Wenn es um floats geht, ist das eine nette Methode rauszufinden, ob "prev_num" im Vergleich zu "current_num" nicht etwas gar klein ist 😉

    Wenn du damit die Genauigkeit von Gleitkommazahlen meinst, dann macht man das aber anders und nicht mit Vergleich auf Gleichheit.



  • groovemaster schrieb:

    Wenn du damit die Genauigkeit von Gleitkommazahlen meinst, dann macht man das aber anders und nicht mit Vergleich auf Gleichheit.

    Wie denn?
    Solche Konstrukte werden doch angewendet, wenn z.B. die Wurzel von irgendwas berechnet werden soll. Die Abbruchbedingungen von Schleifen sind dann genau solche "Spielereien" mit der Genauigkeit der Zahlen.



  • SOLCHE Kontrukte werden eben nicht angewandt. Man überprüft, ob das Ergebnis (welches auch immer) innerhalb einer bestimmten Abweichung liegt. C bietet hier zB einen Epsilon Wert an. Die Überprüfung wird dann aber mit grösser bzw. kleiner (gleich) gemacht und nicht mit Überprüfung auf Gleichheit.



  • das ist doch alles zu 95% gefakt



  • groovemaster schrieb:

    SOLCHE Kontrukte werden eben nicht angewandt. Man überprüft, ob das Ergebnis (welches auch immer) innerhalb einer bestimmten Abweichung liegt. C bietet hier zB einen Epsilon Wert an. Die Überprüfung wird dann aber mit grösser bzw. kleiner (gleich) gemacht und nicht mit Überprüfung auf Gleichheit.

    dem muß ich nicht zustimmen.
    ich hab gerade ein prog gebaut, das nullstellen von polynomen findet.
    hab aber den feinen trick, um den es hier geht, noch nicht eingebaut.

    das problem ist, daß ich, wenn die wurzel so um 1.414 liegt, ich bei diff=1.e-10 fein aufhören kann. aber wenn die wurzel so um 1.e-20 liegt, ich lieber bis 1.e-34 laufen mag.

    ...aufhören kann? irgendwann muß ich aufhören. einfach epsilon geht nicht, da ich auch mal gegen zyklen laufe, die keine kleineren beträge als 1.e-4 haben. wenn ich die würzeln des polynoms 1x4+2x3+3x^2+4x+5 suche, dann fällt der rechner in einen zyklus der länge 84. ich hab nicht 84 speicherstellen zu verfügung. und der rechner ist auch so lahm, daß ich nicht do{a=f(a);b=f(f(b));}while(a!=b); schreiben mag wegen dreifachem rechenaufwand. ich überlege, ob ich brent's algo zweckentfremden kann zur zyklenerkennung und ob das billig ist. aber ungeachtet dessen, kann ich sofort abbrechen, wenn neuerwert-(neuerwert-alterwert)==neuerwert.



  • volkard schrieb:

    das problem ist, daß ich, wenn die wurzel so um 1.414 liegt, ich bei diff=1.e-10 fein aufhören kann. aber wenn die wurzel so um 1.e-20 liegt, ich lieber bis 1.e-34 laufen mag.

    ...aufhören kann? irgendwann muß ich aufhören. einfach epsilon geht nicht, da ich auch mal gegen zyklen laufe, die keine kleineren beträge als 1.e-4 haben. wenn ich die würzeln des polynoms 1x4+2x3+3x^2+4x+5 suche, dann fällt der rechner in einen zyklus der länge 84. ich hab nicht 84 speicherstellen zu verfügung. und der rechner ist auch so lahm, daß ich nicht do{a=f(a);b=f(f(b));}while(a!=b); schreiben mag wegen dreifachem rechenaufwand. ich überlege, ob ich brent's algo zweckentfremden kann zur zyklenerkennung und ob das billig ist. aber ungeachtet dessen, kann ich sofort abbrechen, wenn neuerwert-(neuerwert-alterwert)==neuerwert.

    Ich glaube ich habe gerade meine neue Signatur gefunden... 🤡 👍



  • Doch noch was auf der HD gefunden: kein Grösser/Kleiner, kein Epsilon, und doch funktioniert die Wurzelberechnung 😉

    float value = 3;
    
            float top = value;
            float bottom = 0;
    
            float middle = bottom + (top - bottom)/2;
    
            while( top != middle && bottom != middle ){
                if( middle * middle > value )
                    top = middle;
                else
                    bottom = middle;
    
                middle = bottom + (top - bottom)/2;
            }
    
            System.out.printf( "sqrt %1$f = %2$f\n%2$f*%2$f = %3$f", 
                    value, middle, middle*middle );
    

    Wie das in irgendwelchen zutode optimierten c-libs aussieht, kann ich nicht sagen. Diese Variante mit der Maschinengenauigkeit umzugehen, ist jedenfalls ziemlich robust.



  • wazu ist den das gut?

    float value = 3; 
    
            float top = value; 
            float bottom = 0; 
    
            float middle = bottom + (top - bottom)/2;
    

    wieso nicht gleich

    float middle = value / 2;
    


  • lol, das ist schon echt auch WTF-verdächtig. 😃 👍



  • DEvent schrieb:

    wazu ist den das gut?

    float value = 3; 
            
            float top = value; 
            float bottom = 0; 
            
            float middle = bottom + (top - bottom)/2;
    

    Ein compiler sollte das weg-optimieren. Aber zur Verstaendnis und einfacheren Lesbarkeit schadet es nicht. Im Gegenteil.
    Und wie du unten siehst, werden die Variablen noch genutzt, ohne kommst du also eh nicht aus.

    wieso nicht gleich

    float middle = value / 2;
    

    Wieso nicht gleich float middle = 3 / 2? value is auch konstant. Wenn du schon bei bist, koenntest du natuerlich gleich das Ergebnis des ganzen Algorithmus ausrechnen. 🙂

    --
    Andreas



  • Andreas Kohn schrieb:

    wieso nicht gleich

    float middle = value / 2;
    

    Wieso nicht gleich float middle = 3 / 2?

    Weil da nicht 1.5 rauskommt!



  • Walli schrieb:

    Weil da nicht 1.5 rauskommt!

    aber das programm funktioniert mit 2/3 auch!



  • int isTrueReturnsTrueIfTheArgumentIsTrueAndFalseIfItIsNotTrue(int t)
    {
        //
    }
    


  • volkard schrieb:

    dem muß ich nicht zustimmen.

    Das mit epsilon war ja auch nicht generalisiert zu verstehen. Wenn du für deine Zwecke sowas nicht brauchst, musst du es auch nicht benutzen.

    volkard schrieb:

    aber ungeachtet dessen, kann ich sofort abbrechen, wenn neuerwert-(neuerwert-alterwert)==neuerwert.

    Darf ich trotzdem nochmal fragen, warum du das schreibst und nicht gleich 'alterwert == neuerwert'?



  • if(ahp>=0)
      if(ahp>=mhp*0.1)
        if(ahp>=mhp*0.2)
          if(ahp>=mhp*0.3)
            if(ahp>=mhp*0.4)
              if(ahp>=mhp*0.5)
                if(ahp>=mhp*0.6)
                  if(ahp>=mhp*0.7)
                    if(ahp>=mhp*0.8)
                      if(ahp>=mhp*0.9)
                        if(ahp==mhp)
                        cout<<"   [||||||||||]       ";
                        else
                        cout<<"   [||||||||||]       ";
                      else
                      cout<<"   [||||||||| ]       ";
                    else
                    cout<<"   [||||||||  ]       ";
                  else
                  cout<<"   [|||||||   ]       ";
                else
                cout<<"   [||||||    ]       ";
              else
              cout<<"   [|||||     ]       ";
            else
            cout<<"   [||||      ]       ";
          else
          cout<<"   [|||       ]       ";
        else
        cout<<"   [||        ]       ";
      else
      cout<<"   [          ]       ";
    
     if(asp>=0)
      if(asp>=msp*0.1)
        if(asp>=msp*0.2)
          if(asp>=msp*0.3)
            if(asp>=msp*0.4)
              if(asp>=msp*0.5)
                if(asp>=msp*0.6)
                  if(asp>=msp*0.7)
                    if(asp>=msp*0.8)
                      if(asp>=msp*0.9)
                        if(asp==msp)
                        cout<<"[||||||||||]        ";
                        else
                        cout<<"[||||||||||]        ";
                      else
                      cout<<"[||||||||| ]        ";
                    else
                    cout<<"[||||||||  ]        ";
                  else
                  cout<<"[|||||||   ]        ";
                else
                cout<<"[||||||    ]        ";
              else
              cout<<"[|||||     ]        ";
            else
            cout<<"[||||      ]        ";
          else
          cout<<"[|||       ]        ";
        else
        cout<<"[||        ]        ";
      else
      cout<<"[          ]        ";
    
    if(axp>=0)
      if(axp>=mxp*0.1)
        if(axp>=mxp*0.2)
          if(axp>=mxp*0.3)
            if(axp>=mxp*0.4)
              if(axp>=mxp*0.5)
                if(axp>=mxp*0.6)
                  if(axp>=mxp*0.7)
                    if(axp>=mxp*0.8)
                      if(axp>=mxp*0.9)
                        if(axp==mxp)
                        cout<<"[||||||||||]"<<endl<<endl;
                        else
                        cout<<"[||||||||||]"<<endl<<endl;
                      else
                      cout<<"[||||||||| ]"<<endl<<endl;
                    else
                    cout<<"[||||||||  ]"<<endl<<endl;
                  else
                  cout<<"[|||||||   ]"<<endl<<endl;
                else
                cout<<"[||||||    ]"<<endl<<endl;
              else
              cout<<"[|||||     ]"<<endl<<endl;
            else
            cout<<"[||||      ]"<<endl<<endl;
          else
          cout<<"[|||       ]"<<endl<<endl;
        else
        cout<<"[||        ]"<<endl<<endl;
      else
      cout<<"[          ]"<<endl<<endl;
    break;
    

    😃



  • groovemaster schrieb:

    Darf ich trotzdem nochmal fragen, warum du das schreibst und nicht gleich 'alterwert == neuerwert'?

    Weil die Werte möglicherweie verschieden sind. Dann schlägt der Vergleich nicht an. Ist aber der eine sehr klein im Vergleich zum anderen kann es durch Rundung passieren, daß das Abziehen eben garnichts mehr ändert.



  • Jester schrieb:

    Weil die Werte möglicherweie verschieden sind. Dann schlägt der Vergleich nicht an.

    Das wäre aber bei der Kurzform auch so.

    Jester schrieb:

    Ist aber der eine sehr klein im Vergleich zum anderen kann es durch Rundung passieren, daß das Abziehen eben garnichts mehr ändert.

    Und du erhälst dann '0 == neuerwert'? Aber was soll das bringen?

    So wie ich Volkard verstehe, benutzt er lieber 'neuerwert-(neuerwert-alterwert)==neuerwert' als den Vergleich mit epsilon. Naja, ist wohl Geschmackssache.


Anmelden zum Antworten