Cos (90) liefert einen Wert sehr nahe an 0, aber ich brauche 0?

  • Die Werte für temp_x_btm_left = 0 & amp; temp_y_btm_left = 1;

     angle = 90;
    
    //Moving the bottom left coordinates
    _btm_left.real() = (temp_x_btm_left * cos(angle*PI/180)) 
                       - (temp_y_btm_left * sin(angle*PI/180));
    _btm_left.imag() = (temp_x_btm_left * sin(angle*PI/180)) 
                       + (temp_y_btm_left * cos(angle*PI/180));
     

    Der Code soll das Objekt um 90 Grad gegen den Uhrzeigersinn drehen, was er tut aber _btm_left.imag() gibt einen Wert zurück, der wirklich nahe bei 0 = 1.437949e-009 liegt, und ich brauche wirklich 0.

    Ich habe setprecision() und setw() aber es scheint keine Wirkung zu haben. Gibt es irgendwelche Methoden für so etwas oder muss ich meine eigenen erstellen, um das Problem zu lösen?!

    19 April 2012
    勿绮语Hoppo
5 answers
  • Solange | v1-v2 | & lt; predefinedDelta, betrachten Sie einfach v1 == v2.

    19 April 2012
    勿绮语Hoppo
  • Die trigonometrischen Funktionen verwenden ein Argument im Bogenmaß, nicht in Grad. Ihre Berechnung von angle*PI/180 ergibt nicht genau PI / 2, was natürlich nicht als Gleitkommazahl dargestellt werden kann.

    Eine Lösung wäre ein Vergleich mit speziellen Werten vor die Umwandlung in Radiant, e. g.

     if (angle == 90.0)
        x = 0.0
    else
        x = cos(angle*PI/180.0)
     
    22 November 2011
    Gunther Piez
  • Das "magische Epsilon", auf das in vorherigen Antworten verwiesen wurde, wird tatsächlich von der Sprache über

      #include <limits>
     std::numeric_limits<float>::epsilon();
     
    und

      std::numeric_limits<double>::epsilon();
     

    ist "die Differenz zwischen 1 und dem kleinsten darstellbaren Wert größer als 1"

    22 November 2011
    Walter
  • Eine Lösung wäre, einen Epsilon gleich einem magischen kleinen Wert festzulegen und dann zu prüfen, ob der absolute Wert Ihres Ergebnisses, den eine Funktion liefert, kleiner (oder kleiner oder gleich) zu Ihrem [ist. && 1&&].

    (Die Benennung von Epsilon ist nur eine Konvention; es könnte auch double MagicalNumberIndeed = VerySmallValue; sein)

    22 November 2011
    Lightness Races in OrbitMarco Aurélio Deleu
  • Berechnen Sie Ihre Winkelberechnungen vorab und verwenden Sie dann die Ergebnisse. Etwas wie:

     if (angle == 90) {
      cos_angle = 0
    } else {
      cos_angle = cos(angle)
    }
    ...
    _btm_left.real() = ... * cos_angle ...
     

    Dies hat den zusätzlichen Vorteil, dass weniger Anrufe an cos() und sin() getätigt werden.

    Denken Sie daran, dass, wenn angle ein Float ist, etwas wie angle == 90 etwas tun könnte, da die internen Werte von Gleitkommazahlen intern dargestellt werden. Möglicherweise möchten Sie dies in etwas ändern:

     if (abs(angle-90) < some_small_number) {
     
    22 November 2011
    CanSpiceDamien Praca