Announcement

Collapse
No announcement yet.

Umwandlung double zu integer ohne Runden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Umwandlung double zu integer ohne Runden

    Hallo mal wieder,
    ich möchte aus einer double mit 3 Nachkommastellen einen integer-Wert machen. Dabei soll allerdings nicht gerundet, sondern direkt nach dem Komma abgeschnitten werden. Bspw:
    0.3 => 0
    0.4 => 0
    0.9 => 0
    1.0 => 1
    1.9 => 1

    etc.

    Wie geht das?
    Vielen Dank für Eure Hilfe!

  • #2
    double d=1.9;
    int x=d;
    Christian

    Comment


    • #3
      Hi Christian,
      danke mal wieder für deine Hilfe.

      Ich habe aber noch eine Frage: Geht es auch ohne die Definition einer neuen Variable?
      Ich habe nämlich in mehreren großen Matrizen viele Werte gepeichert (als double). Nun möchte ich einfach in eine Datei die besagten Werte manchmal als integer (ungerundet) per fprintf schreiben...

      Comment


      • #4
        irgendwie ist die Frage unverständlich:

        Geht es auch ohne die Definition einer neuen Variable?
        viele Werte gepeichert (als double).
        manchmal als integer (ungerundet)
        Was den nun ??

        Wann ist manchmal?

        Grundsätzlich geht es auch ohne eine neue Variable:

        double d=1.9;
        d=abs(d);

        Dann ist der ursprüngliche Wert jedoch futsch
        Christian

        Comment


        • #5
          Ah ich habe den Befehl abs() gesucht, danke!

          Ich wollte einfach in einer Jahresbetrachtung neben t (was halt Nachkommastellen besitzt) auch den integer-Wert des Jahres ausgeben.

          Mache das jetzt über
          fprintf(datei, "%d\n", abs(t));

          Danke nochmal!

          Comment


          • #6
            Originally posted by Verwirrter_Anfaenger View Post
            Ah ich habe den Befehl abs() gesucht, danke!

            Ich wollte einfach in einer Jahresbetrachtung neben t (was halt Nachkommastellen besitzt) auch den integer-Wert des Jahres ausgeben.

            Mache das jetzt über
            fprintf(datei, "%d\n", abs(t));

            Danke nochmal!
            Also abs() dürfte wohl nicht der Befehl sein, den du gesucht hast. abs() bildet den Absolutwert einer Zahl, sprich sie schmeißt das Vorzeichen weg, aber nicht die Nachkommastellen! abs() gibt folgliche auch eine double-Zahl zurück, und kein int. Was du machen möchtest, geht jedoch noch viel einfacher, nämlich mit einem cast:

            i = (int) d;

            bzw. für größere Zahlen analog

            l = (long) d;
            ll = (long long) d;


            Für obiges Beispiel also:

            fprintf(datei, "%d\n", (int) t);

            Der ANSI Standard definiert erstaulicherweise keine Rundungsfunktion, die kann man sich mit einem Makro aber auch leicht selbst bauen, wenn der Compiler keine Rundungsfunktion mitbringt.

            Comment


            • #7
              Tja, bei mir sind auch die Nachkommastellen futsch.

              Des Weiteren:

              i = (int) d;
              Siehe Beitrag 2-> ein casten nicht notwendig

              Der ANSI Standard definiert erstaulicherweise keine Rundungsfunktion, die kann man sich mit einem Makro aber auch leicht selbst bauen, wenn der Compiler keine Rundungsfunktion mitbringt.
              Ein Runden war nicht gewünscht -> Beitrag 1
              Christian

              Comment


              • #8
                Originally posted by Christian Marquardt View Post
                Tja, bei mir sind auch die Nachkommastellen futsch.
                Ja natürlich, er wollte es aber ohne neue Variable machen. Und da war das Beispiel mit dem abs() nicht korrekt, denn es liefert nicht das gewünschte Ergebnis.

                Originally posted by Christian Marquardt View Post
                Des Weiteren:

                Siehe Beitrag 2-> ein casten nicht notwendig
                Du meinst du must in deinem Beispiel das cast nicht *hinschreiben*.

                double d=1.9;
                int x=d;

                Die zweite Zeile ist durchaus ein cast, nämlich ein implizites, was der Compiler für dich automatisch einsetzt.

                Im Beispiel mit

                fprintf(datei, "%d\n", ...);

                darf man leider nicht auf ein implizites cast hoffen, weil die Funktion ab dem dritten Parameter via Ellipse keine Typprüfung mehr vornimmt. So wäre der Audruck

                fprintf(datei, "%d\n", t); // mit t = double

                undefiniert(!) und falsch, auch wenn der Compiler nicht meckert. In der Ausgabe steht nur Müll, weil die 8 Bytes der double Zahl via "%d" als 4 Byte int interpretiert werden - Autsch! Der GCC kennt anbei bemerkt den Schalter -Wformat, der solche Fehler erkennt und ein Warning ausgibt.

                Stattdessen muss hier explizit gecastet werden:

                fprintf(datei, "%d\n", (int) t);

                (Oder man möchte tatsächlich ein double rausschreiben, dann z. B. mit

                fprintf(datei, "%.15g\n", t);
                )

                Originally posted by Christian Marquardt View Post
                Ein Runden war nicht gewünscht -> Beitrag 1
                Das war auch nur als zusätzliche Anmerkung gedacht, denn nach der Frage "Wie schmeiße ich die Nachkommastellen weg?" kommt meist die Frage "Und wie runde ich richtig?". - Ja wohin denn überhaupt? Auf, ab oder kaufmännisch? ;-)

                Cheerz

                Don

                Comment


                • #9
                  Ich weiss nicht was der VC Compiler macht (anscheinend ja so einiges nicht richtig ;-) ). Borland liefert bei abs das

                  Die zweite Zeile ist durchaus ein cast, nämlich ein implizites, was der Compiler für dich automatisch einsetzt.
                  Mir wohl bekannt, aber warum extra hinschreiben? Warum einen Anfänger (und einen verwirrten dazu) mit sowas "belasten". Als Anfänger reicht es zu wissen, wenn ich das so un so mache kommt das bei raus. Im Laufe der Zeit kommt dann von ganz allein die eine oder andere Erkenntnis. Ist jedenfalls meine Philosophie. Nicht gleich mit der hundersten Ausnahmen und xten-Erklärung überladen. Auch wie ich finde, das man nicht immer gleich die Lösung posten muss. Ein bisssssschen Hilfe zur Selbsthilfe. Und - aus wenn es hier nicht so beliebt ist - -> auch Fragen richtig stellen (ist jetzt nicht auf diesen Thread bezogen).
                  Christian

                  Comment


                  • #10
                    Originally posted by Christian Marquardt View Post
                    Ich weiss nicht was der VC Compiler macht (anscheinend ja so einiges nicht richtig ;-) ). Borland liefert bei abs das
                    Moin, moin!

                    ich glaube wir kommen der Sache langsam etwas näher... ;-)
                    Stellen wir uns also mal ganz dumm, schauen in die Hilfe und gucken uns die Funktionsdefinitionen an. M$ VC sagt zu abs() das hier:

                    Calculate the absolute value. (= schmeiße Vorzeichen weg, bilde den Betrag)

                    int abs(
                    int n
                    );

                    Also: Das ist also ein *Integer* Abs()!
                    Wenn ich das ***unter nacktem C*** so aufrufe:

                    d = abs(d)

                    dann macht der Compiler daraus in etwa:

                    int itemp;
                    itemp = (int) d;
                    itemp = abs(itemp);
                    d = (double) itemp;

                    -> Ergo: 2 * impliziter cast. Dabei fliegen dann *als Nebeneffekt* zusätzlich die Nachkommastellen in die Tonne! Nebeneffekte sind unschön...

                    Unter C++ gibt es dann überladen *außerdem* noch:

                    long abs(
                    long n
                    ); // C++ only

                    double abs(
                    double n
                    ); // C++ only

                    long double abs(
                    long double n
                    ); // C++ only

                    float abs(
                    float n
                    ); // C++ only

                    Unter C++ wird der Compiler also sinnvollerweise das Rumgecaste sein lassen und sich für die Version

                    double abs(
                    double n
                    ); // C++ only

                    entscheiden. Und in diesem Fall ist dann:
                    double d = 3.1415;
                    d = abs(d);
                    // d immer noch 3.1415, Nachkommastellen bleiben hier erhalten

                    d = -3.1415;
                    d = abs(d);
                    // d jetzt +3.1415, Nachkommastellen bleiben wieder erhalten, aber dafür Vorzeichen umgedreht!

                    Die obigen Überladungen sind eigentlich ANSI konform und in stdlib.h bzw. math.h enthalten (Details: -> Stroustrup). Jetzt fragt sich dann, warum dein Borland Compiler die int-Version von abs heranzieht, MS aber die (IMHO richtigere) double-Version? Lt. Screenshot hast du nicht unter C kompiliert. Was für Header hast du denn includiert?

                    Also wenn ich mir überlege, dass je nach Compiler evtl. eine andere Funktion genommen wird, ohne dass dies offensichtlich ist und ich dieses "ich weiß nicht was sie zurückgibt" dann auch noch an printf und Konsorten übergebe, in der Meinung ein %d wird schon richtig sein, und dann ist's doch ein double, dann darf man sich nicht wundern, wenn das Programm alles mögliche macht, aber sicher nicht das was man erwartet...

                    Originally posted by Christian Marquardt View Post
                    Warum einen Anfänger (und einen verwirrten dazu) mit sowas "belasten".
                    Ich glaube der verwirrte Anfänger hat sich hier schon längst ausgeklinkt, weil er eh nur noch Bahnhof versteht! ;-)))
                    (nichts gegen den verwirrten Anfänger, so hat auch der beste Profi mal angefangen)

                    Cheerz

                    Don

                    Comment


                    • #11
                      Als *.c:

                      #include <math.h>
                      int main(int argc, char* argv[])
                      {
                      double d=-3.1415;
                      d=abs(d);
                      return 0;
                      }
                      Ergebnis 3

                      #include <stdlib.h>
                      int main(int argc, char* argv[])
                      {
                      double d=-3.1415;
                      d=abs(d);
                      return 0;
                      }
                      Ergebnis 3

                      Als *.cpp

                      #include <math>
                      int main(int argc, char* argv[])
                      {
                      double d=-3.1415;
                      d=abs(d);
                      return 0;
                      }
                      Ergebnis 3

                      #include <stdlib>
                      int main(int argc, char* argv[])
                      {
                      double d=-3.1415;
                      d=abs(d);
                      return 0;
                      }

                      Ergebnis 3



                      Hier was Borland dazu schreibt für math.h und stdlib.h:

                      Rückgabewert Die Funktion abs gibt einen Integerwert im Bereich von 0 bis INT_MAX zurück, ausgenommen, das Argument hatte den Wert INT_MIN, der als INT_MIN zurückgegeben wird. Die Werte für INT_MAX und INT_MIN sind in der Header-Datei limit.h definiert.

                      Insofern also immer eine int.....

                      Die überladenen Funktionen habe ich hier nicht gefunden.....

                      Dafür ein labs -> long
                      ein fabs -> float

                      aber kein dabs
                      Zuletzt editiert von Christian Marquardt; 13.07.2007, 06:32.
                      Christian

                      Comment

                      Working...
                      X