Die Zahl 0 erscheint negativ



  • Hallo,

    ich hab einen Code geschrieben, der eine Matrix A und einen Vektor b bekommt und die Gleichung A*x=b durch die Rückwärstsubstitution löst, wobei A in Dreiecksform gegeben ist (diese Angabe ist eig. für mein Problem unwichtig...)

    Als Ergebnis wird der Vektor ausgegeben, also in der Art:

    AUSGABE MATRIX A:
    (1,3,4)
    (0,-4,-7)
    (0,0,1)
    
    AUSGABE VON LOESUNG X:
    x1: 2   x2: 5   x3: -5
    

    Das ist ja alles schön und gut, allerdings, wenn z.B. einer der x-Werte 0 wird, dann erscheint es in der Konsole als -0. Kann man sowas beheben? Ok, es führt nicht zu Rechenfehlern oder so, aber es sieht bei der Ausgabe unschön aus. Ich hab gedacht, dass ich es mit if Abfange, aber vllt gibt es dafür ja C++-spezifische Konstrukte...

    Lg, lil



  • lil_pingu schrieb:

    Das ist ja alles schön und gut, allerdings, wenn z.B. einer der x-Werte 0 wird, dann erscheint es in der Konsole als -0.

    Würdest du bitte den Teil deines Codes zeigen, der für die Ausgabe relevant ist (inklusive Datentypen)?

    std::cout << 0; // Gibt zumindest hier 0 (und nicht -0) aus
    


  • braucht ja bloss irgendwo ein negativer faktor zu sein:
    cout << -1.0 * 0;



  • cout << -1.0 * 0;

    Gibt bei mir 0 ohne Minus aus.



  • Lass mich raten: es ist ein double Wert. Dann hast du verloren. Zwar gibt der stream "0" aus, aber das ist nur der aufgerundete Wert von -0.000......01. Negativ ist das Ganze trotzdem(da nicht exakt 0) darum ist das Ergebnis -0.

    Eine Lösung wäre zu schauen, ob das Ergebnis hinreichend nahe 0 ist und diesen Fall per Hand abzufangen. Sonst wüsste ich nichts.



  • // x[n] = b[n] / a(n,n)
    	int n = x.length(); //Length ermittelt Anzahl der elem in der Liste
    	x[n] = b[n] / (A.get(n,n));
    
    	// Rückwärst einsetzen
    	for(int i = n - 1; i >= 0; i--){
    		int summe = 0;
    		for(int k = i+1; k<= n; k++){
    			int a = A.get(i,k);
    			summe = summe + (a*x[k]);
    		}
    		x[i] = (b[i] - summe)/(A.get(i,i));
    	}
    
    	// Ausgabe des x-Vektors
    	cout << "\nAUSGABE VON X: ";
    		for(int i = 0; i <= n; i++){
    			cout << "x[" << i << "]: " << x[i] << endl;
    		}
    	cout << endl;
    

    Ich könnte natürlich die Werte in der äußeren for-Schleife abfangen und wenn jedesmal eine 0 kommt, den Wert als positive Null reinschreiben, aber gibt es keine bessere Möglichkeit?



  • otze schrieb:

    Lass mich raten: es ist ein double Wert. Dann hast du verloren. Zwar gibt der stream "0" aus, aber das ist nur der aufgerundete Wert von -0.000......01. Negativ ist das Ganze trotzdem(da nicht exakt 0) darum ist das Ergebnis -0.

    Eine Lösung wäre zu schauen, ob das Ergebnis hinreichend nahe 0 ist und diesen Fall per Hand abzufangen. Sonst wüsste ich nichts.

    Ja es waren double-Werte....dann muss ich es wohl per Hand abfangen... 😞



  • Nur so nebenbei: Alle Fließkommadarstellungen, die ich kenne, besitzen zwei Nullen: +0 und -0. Das liegt daran, dass sie das Vorzeichen und den Betrag separat speichern.

    Ob bei der Ausgabe -0 oder 0 steht, interessiert mich eigentlich herzlich wenig.

    Sonst ist es noch Sache der Implementierung von operator<<(ostream&, double). Das folgende Programm

    #include <ios>
    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <sstream>
    #include <climits>
    
    std::string raw2str(unsigned char const* p, unsigned length)
    {
      using std::ios;
      using std::setw;
      std::stringstream ss;
      ss.flags(ios::hex | ios::left);
      ss.fill('0');
      for (unsigned i=0; i<length; ++i) {
        if (i>0) ss << ' ';
        ss << setw((CHAR_BIT+3)/4) << unsigned(p[i]);
      }
      return ss.str();
    }
    
    template<typename T>
    inline std::string raw2str(T const& x)
    {
      return raw2str(reinterpret_cast<unsigned char const*>(&x),sizeof(T));
    }
    
    double negate(double x) {
      return -x;
    }
    
    int main()
    {
      double a = 0.0;
      double b = -a;
      std::cout << raw2str(a) << "  -->  " << a << '\n';
      std::cout << raw2str(b) << "  -->  " << b << '\n';
      std::cout << std::boolalpha << (a==b) << '\n';
    }
    

    liefert bei mir die Ausgabe:

    00 00 00 00 00 00 00 [b]00[/b]  -->  0
    00 00 00 00 00 00 00 [b]80[/b]  -->  0
    true
    

    Auf meinem System (double = IEEE-754 64-Bit Fließkommazahl, Little Endian Byte-Ordnung) ist das höchstwertige Bit im letzten Byte das Vorzeichen.
    Trotzdem sehe ich bei der Ausgabe als Zeichenkette kein Minus.

    Gruß,
    SP



  • Sebastian Pizer schrieb:

    Trotzdem sehe ich bei der Ausgabe als Zeichenkette kein Minus.

    Ich nehme an, er hat das -0.00000 oder -0 bei double d=-0.00000000001; cout<<d;


Anmelden zum Antworten