Hilfe, QBasic rechnet falsch

Von: , Frage gestellt am Mo, 6. Jun 2005

Hallo,

Statt mit dem Taschenrechner wollte ich lange Zahlenreihen
in QBasic eingeben.
Am Ende wird alles in eine TXT-Datei gespeichert.
Diese TXT-Datei brauche ich zum späteren Ausdruck und zur
Kontrolle.
BETRAG(I) wird am Ende in TXT gespeichert

FOR I .....
INPUT A
IF A = 0 THEN...... ;(Ausstieg aus Schleife)
BETRAG(I) = BETRAG(I) + A
A = A + A
PRINT A

Es werden eigentlich nur einfache Werte eingetippt, wie
57.00, 12.80, 7.65 etc.

Das funktioniert auch.
Doch plötzlich, an bestimmten Stellen erscheint eine "krumme"
Zahl.
Eigenartigerweise immer an der gleichen Stelle.
Wie z.B. bei 82.30
Da tippe ich dann 13.70 ein.
Angezeigt wird dann 95.99999 statt glatte 96

Rechne ich im Direktmodus beide Zahlen, dann erscheint auch
das richtige Ergebnis (96).

Tippe ich weitere Beträge ein, stimmt irgendwann wieder alles.
Bis irgendwo wieder so krumme Zahlenreihen entstehen.

Das darf und kann doch eigentlich nicht sein.

Was kann das sein?

Klaus

7 Antworten zu dieser Frage

  1. Antwort von nach 48 Minuten 0 hilfreich
    Re: Hilfe, QBasic rechnet falsch

    Doch plötzlich, an bestimmten Stellen erscheint eine "krumme"
    Zahl.
    Eigenartigerweise immer an der gleichen Stelle.
    Wie z.B. bei 82.30
    Da tippe ich dann 13.70 ein.
    Angezeigt wird dann 95.99999 statt glatte 96
    Das ist ein typisches Problem bei der Verwendung von Fließkommazahlen. Der Computer rechnet binär, dein Eingaben sind aber dezimal. Vor dem Komma ist das kein Problem, sobald du aber mit Nachkommastellen arbeitest, kann der Computer Dezimalzahlen nicht mehr 1 zu 1 in Binärzahlen abbilden, es kommt zwingend zu Rundungsfehlern (Versuch mal 7/10 als eine Summe von Werten der Folge 1/(2*x); x€N darzustellen).

    Für kaufmännisches Rechnen solltest du daher grundsätzlich ausschliesslich mit Ganzzahlen (Integer) arbeiten. Die Aufbereitung der Werte mit zwei Nachkommastellen in der Ein- und Ausgabe musst du dann, wenn die Programmiersprache dies für dich nicht automatisch übernehmen kann, selbst programmieren. QBasic ist für solche Aufgaben nicht unbedingt die geeignetste Sprache.

    Gruss
    Schorsch

    • Antwort von nach einer Stunde 0 hilfreich
      Kleine Korrektur

      Vor dem Komma ist das kein Problem
      Auch diese Aussage ist nur dann korrekt, wenn du tatsächlich mit ganzzahligen Variablentypen arbeitest. Bei der Darstellung von Ganzzahlen in Variablen vom Typ Gleitkomma werden auch diese intern in Exponentialschreibweise gewandelt und sind entsprechend mit Rundungsfehlern behaftet. Der Rundungsfehler ist dabei um so grösser, je kleiner die Mantisse gewählt wird, bei QBasic dürften das gerade mal 22 bit sein.

      Gruss
      Schorsch

  2. Antwort von nach 5 Stunden 0 hilfreich
    Re: Hilfe, QBasic rechnet falsch

    Äh!

    Ich bin ja schon Grufti.
    Das bisschen coden habe ich am C64 gelernt.
    Dadurch fällt es mir leichter, auch andere Programmiersprachen
    zu erlernen.
    1. habe ich keine Progs wie VB oder so,
    2. wollte ich mir die Sache nur erleichtern.

    Dafür ein aufwändiges Programm zu coden wäre (für diese Sache)
    uneffektiv.
    Wenn ich das richtig verstanden habe, dürfte ich nur Ganzzahlen
    eingeben.

    Vielleicht kapiere ich das nicht richtig.
    Die gleiche Programmfolge habe ich mit einem C64 Emulator
    getestet (also als C64 Programm).

    Einwandfrei. Da ist der Fehler nicht.
    Ich bin kein Profi und kein Mathematiker, doch irgendwie ist das
    unlogisch.
    Ein C64 rechnet ja auch Binär.

    QBasic im Vergleich zum C64 Basic ist so, als wenn man
    VB mit QBasic vergleicht.

    Trotzdem ist das für meine Logik ein Bug.
    Ist egal, wie das intern umgerechnet wird.
    Wenn da solche Zahlen herauskommen, wird es FALSCH umgerechnet.

    Meine Meinung.

    Natürlich lässt sich alles Chaotische auch logisch erklären.
    Das geht mit Programmiersprachen los.
    ; als Zeilenende andere unmögliche Zeichen wie gescheifte Klammern.

    DOS erkennt Zeilenenden auch ohne ; usw.
    Es liegt also an die Entwickler der Prog-Sprachen.

    Es mag ja einiges Sinn haben.
    Nur ein kleines, unbedeutendes Beispiel:
    Statt z.B. A$ wird jetzt geschrieben $A
    Warum?
    Was bringt das?
    NICHTS
    Die Funktion, der Sinn ist gleich, nur die Syntax ist anders.
    So setzt sich das dann fort.

    So hat dann jede Prog.Sprache z.T. eine eigene Syntax.
    Total idiotisch.
    Oder Javascript.
    Ist nicht in der Lage bestimmte, zusammenhängende Befehlszeilen
    zu erkennen, es sei, mit dem + Zeichen.

    Ich meine:
    Es geht auch anders.
    Das hat nicht mit "höhere" Programmierung zu tun, sondern ist einfach
    nur chaotisch.
    PHP z.B. wird als "einfache" Programmiersprache angepriesen.
    So einfach ist die auch nicht, aber effektiv durchdacht.

    Klaus

    • Antwort von nach 7 Stunden 0 hilfreich
      Re^2: Hilfe, QBasic rechnet falsch

      Hi Klaus, Trotzdem ist das für meine Logik ein Bug.
      Ist egal, wie das intern umgerechnet wird.
      Wenn da solche Zahlen herauskommen, wird es FALSCH
      umgerechnet.
      Im Prinzip hast Du ja auch Recht. Die Programmieren von QBasic hätten eine Stelle weniger anzeigen und dafür runden können. Bei der geringen Kapazität der Rechner damals hat man aber darauf verzichtet.
      Wenn Du einen Abakus verwendest, darfst Du halt nicht erwarten, daß er Dir numerische integrale vollautomatisch errechnet. Nimm wenigstens einen Taschenrechner. (VB?) ;-)
      VB ist genau so leicht zu bedienen wie das Basic vom C64, sogar die Syntax ist fast identisch. Die Unterschiede sind offensichtlich und VB hilft auch ungefragt. Bei VB mußt Du die Syntax nicht lernen, VB erklärt sie während der Arbeit ständig selbst. Meine Meinung.

      Natürlich lässt sich alles Chaotische auch logisch erklären.
      Das geht mit Programmiersprachen los.
      ; als Zeilenende andere unmögliche Zeichen wie gescheifte
      Klammern.

      DOS erkennt Zeilenenden auch ohne ; usw.
      Es liegt also an die Entwickler der Prog-Sprachen.
      Ja, da waren wohl einfach die Entwickler der Editoren und Compiler zu faul, das anders zu machen und haben das dem Anwender aufgebrummt.
      Die Vorteile, die es bringt, daß man das Zeilenende selbst markieren muß, sind sehr gering. Auf VB4 bis VB6 trifft das aber nicht zu. Es mag ja einiges Sinn haben.
      Nur ein kleines, unbedeutendes Beispiel:
      Statt z.B. A$ wird jetzt geschrieben $A
      Warum?
      Was bringt das?
      NICHTS
      Die Funktion, der Sinn ist gleich, nur die Syntax ist anders.
      So setzt sich das dann fort.
      Beispiel VB? Da reicht A. $ brauchst Du gar nicht mehr schreiben. So hat dann jede Prog.Sprache z.T. eine eigene Syntax.
      Total idiotisch.
      Oder Javascript.
      Ist nicht in der Lage bestimmte, zusammenhängende
      Befehlszeilen
      zu erkennen, es sei, mit dem + Zeichen.

      Ich meine:
      Es geht auch anders.
      Das hat nicht mit "höhere" Programmierung zu tun, sondern ist
      einfach
      nur chaotisch.
      PHP z.B. wird als "einfache" Programmiersprache angepriesen.
      So einfach ist die auch nicht, aber effektiv durchdacht.
      Es hilft schon, wenn während dem Tippen die Syntax erklärt wird.
      Sieh Dir VB6 mal an.

      Gruß, Rainer

    • Antwort von nach 8 Stunden 0 hilfreich
      Re^2: Hilfe, QBasic rechnet falsch

      Vielleicht kapiere ich das nicht richtig.
      Die gleiche Programmfolge habe ich mit einem C64 Emulator
      getestet (also als C64 Programm).

      Einwandfrei. Da ist der Fehler nicht.
      Ich bin kein Profi und kein Mathematiker, doch irgendwie ist
      das
      unlogisch.
      Ein C64 rechnet ja auch Binär.
      Das war dann nichts weiter als ein glücklicher Zufall. Der C64 kennt überhaupt noch keine dezidierten Variablentypen für numerische Werte, intern rechnet er, sofern es sich nicht um Schleifeninvarianten handelt, meiner Erinnerung nach grundsätzlich mit Gleitkommawerten. Erst bei der Ausgabe der Werte per print-Befehl rundet er dann wieder.

      Ich kann mich aber noch dunkel an Situationen erinnern, in denen Vergleiche (IF A$ = B$ THEN...) an genau diesem Problem fehlschlugen, weil er da eben nicht rundet, und 17,999999998 ist nun mal nicht gleich 18. Und diese Probleme traten schon dann auf, wenn A$ oder B$ als Summe einstelliger ganzer Zahlen gebildet wurden.

      Das ist mit modernen Programmiersprachen übrigens nicht anders, das passiert z. B. mit Perl genauso, auch andere Sprachen haben die gleichen Probleme, wenn die Variablen auf den falschen Typ deklariert sind. Daher sollten Variablen mit Festkommawerten grundsätzlich als Integer deklariert werden, auch dann, wenn sie eine feste Zahl von Nachkommastellen haben.

      Und, auch in der kaufmännischen Rechnung wichtig, wenn komplexere Rechnungen mit Gleitkommawerten vorgenommen werden müssen, muss der Programmierer immer auf angemessene Rundung achten. Sonst werden aus Rundungsfehlern von millionstel Cent u. U. durch ihre Kumulation am Jahresende leicht mal einige zehntausend Euro Buchungsdifferenz. Gut, vielleicht nicht bei den Grössenordnungen, in denen du rechnest.

      Gruss
      Schorsch

      • Antwort von nach 9 Stunden 0 hilfreich
        Schon wieder Korrektur

        Das war dann nichts weiter als ein glücklicher Zufall. Der C64
        kennt überhaupt noch keine dezidierten Variablentypen für
        numerische Werte, intern rechnet er, sofern es sich nicht um
        Schleifeninvarianten handelt, meiner Erinnerung nach
        grundsätzlich mit Gleitkommawerten. Erst bei der Ausgabe der
        Werte per print-Befehl rundet er dann wieder.
        Dass ich mich dauernd korrigieren muss... peinlich, peinlich. Natürlich kennt auch das C64-Basic schon Integervariablen, diese werden dann mit % statt $ deklariert. Und sofern auf korrekte Variablendeklaration geachtet wird, rechnet er auch durchaus korrekt. Probleme treten auch hier erst bei falscher Variablendeklaration auf.

        Gruss
        Schorsch

        • Antwort von nach 18 Stunden 0 hilfreich
          Re: Schon wieder Korrektur

          Hallo Schorsch, Dass ich mich dauernd korrigieren muss... peinlich, peinlich.
          Natürlich kennt auch das C64-Basic schon Integervariablen,
          diese werden dann mit % statt $ deklariert. Und sofern auf
          korrekte Variablendeklaration geachtet wird, rechnet er auch
          durchaus korrekt. Probleme treten auch hier erst bei falscher
          Variablendeklaration auf.
          Wenn ich das noch recht im Kopf habe war das doch so:
          A = Numerisch, Floating Point
          A$ = String
          A% = Integer

          MfG Peter(TOO)

Keine passende Antwort gefunden? Jetzt eigene Frage stellen!