Seite 1 von 1

select mit Dezimalzahlen

Verfasst: 18.04.2017 19:57
von Micky91
Folgende Situation. Ich habe Dezimalzahlen (1, 1.5, 2, 2.5, 3, 3.5 ...)
Mit den .5 Zahlen geht dies nicht und bringt immer das Ergebnis für den ersten Wert (1)
In der Dokumentation steht, das beim Befehl "select" die Zahlen aufgerundet werden.
Also dachte ich mir, ich wandle die Zahlen in einen String um (strg($x))
Doch leider werden zwar jetzt alle Ganzzahlen richtig interpretiert, aber die.5 Werte weiterhin nicht.
Was mach ich da falsch?

Code: Alles auswählen

select Str(*Cache\difficulty)
    Case "1"
      diffimage$ = GetCurrentDirectory() + image_star_1_0$
    Case "1.5"
      diffimage$ = GetCurrentDirectory() + image_star_1_5$
    Case "2"
      diffimage$ = GetCurrentDirectory() + image_star_2_0$
    Case "2.5"
      diffimage$ = GetCurrentDirectory() + image_star_2_5$
    Case "3"
      diffimage$ = GetCurrentDirectory() + image_star_3_0$
    Case "3.5"
      diffimage$ = GetCurrentDirectory() + image_star_3_5$
    Case "4"
      diffimage$ = GetCurrentDirectory() + image_star_4_0$
    Case "4.5"
      diffimage$ = GetCurrentDirectory() + image_star_4_5$
    Case "5"
      diffimage$ = GetCurrentDirectory() + image_star_5_0$
 EndSelect

Re: select mit Dezimalzahlen

Verfasst: 18.04.2017 20:28
von mk-soft

Code: Alles auswählen

fVal.f = 1.5
iVal.i = (fVal * 10.0)
Debug iVal

Select iVal
    Case 10
      diffimage$ = GetCurrentDirectory() + image_star_1_0$
    Case 15
      diffimage$ = GetCurrentDirectory() + image_star_1_5$
    Case 20
      diffimage$ = GetCurrentDirectory() + image_star_2_0$
    Case 25
      diffimage$ = GetCurrentDirectory() + image_star_2_5$
    Case 30
      diffimage$ = GetCurrentDirectory() + image_star_3_0$
    Case 35
      diffimage$ = GetCurrentDirectory() + image_star_3_5$
    Case 40
      diffimage$ = GetCurrentDirectory() + image_star_4_0$
    Case 45
      diffimage$ = GetCurrentDirectory() + image_star_4_5$
    Case 50
      diffimage$ = GetCurrentDirectory() + image_star_5_0$
 EndSelect

Re: select mit Dezimalzahlen

Verfasst: 19.04.2017 19:58
von GPI
Ich denke du bist über das Problem gestolpert, das Floats immer "schätzwerte" sind.

kannst du einfach mit einen

Code: Alles auswählen

debug Str(*Cache\difficulty)
überprüfen

wobei STR falsch ist - das ist für integer, du suchst StrF bzw. StrD

Wobei ich das vermutlich anders lösen würde. bspw. mit zwei Variablen. bspw. so:

Code: Alles auswählen

Difficult.i=3
DiffFactor.d=Difficult/2.0 
das .0 ist wichtig, damit PB gezwungen wird, in Double zu berechnen..

Re: select mit Dezimalzahlen

Verfasst: 23.04.2017 20:50
von Nino
Micky91 hat geschrieben:Folgende Situation. Ich habe Dezimalzahlen (1, 1.5, 2, 2.5, 3, 3.5 ...)
Mit den .5 Zahlen geht dies nicht und bringt immer das Ergebnis für den ersten Wert (1)
In der Dokumentation steht, das beim Befehl "select" die Zahlen aufgerundet werden.
Also dachte ich mir, ich wandle die Zahlen in einen String um (strg($x))
Doch leider werden zwar jetzt alle Ganzzahlen richtig interpretiert, aber die.5 Werte weiterhin nicht.
Was mach ich da falsch?
Folgendes steht dazu in der Dokumentation von Select:
Hinweis: Select akzeptiert auch Fließkommazahlen (Floats) als <Ausdruck1>, rundet diese jedoch auf die nächstgelegene Ganzzahl (Integer) ab (Vergleiche werden nur mit Ganzzahlen durchgeführt).
Ich finde die Aussage klar.

In der Konsequenz bedeutet das, dass Du entweder Ganzzahlen benutzen solltest (wie von mk-soft vorgeschlagen) oder statt Select/Case lauter If/ElseIf-Zweige (wobei dann allerdings das Problem mit der allgemeinen Fließkommazahlen-Ungenauigkeit auftreten kann, das GPI schon ansprach).

Re: select mit Dezimalzahlen

Verfasst: 24.04.2017 11:02
von NicTheQuick
0.5er-Werte sind aber in der Regeln genau. Denn 0,5 = 2^(-1), ist also korrekt darstellbar in Binärform. Das sollte also mit If-Else funktionieren.

Idealerweise arbeitet man bei Vergleichen mit Fließkommazahlen allerdings mit einem Epislon und Differenzen:

Code: Alles auswählen

If Abs(soll - ist) < Epsilon : Tuwas : EndIf
Wobei Epsilon ein möglichst kleiner Wert ist, z.B. 0.00001. Je nachdem wie hoch die Genauigkeit sein soll.

__________________________________________________
Code-Tags repariert
25.04.2017
RSBasic

Re: select mit Dezimalzahlen

Verfasst: 24.04.2017 21:39
von GPI
Falls sich wer fragt, was ich mit ungenauigkeit meine:

Code: Alles auswählen

a.f=0.4
b.f

For i=1 To 100000
  b+a
Next
Debug "b:"+b
Debug "a:"+a


c.d=0.4
d.d

For i=1 To 100000
  d+c
Next
Debug "d:"+d
Debug "c:"+c
Debug "c:"+StrD(c,17)
0.4 lässt sich nicht binär darstellen. Das ist aber kein Fehler, wir haben in 10er-System das gleiche mit 1/3. Jenachdem wie diese 0.5 berechnet werden, kann es zu ungenauigkeiten kommen. Deshalb bspw. das Konstrukt von Nic mit Epsilon.