Frage zu Float-Werten

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
dllfreak2001
Beiträge: 2925
Registriert: 07.09.2004 23:44
Wohnort: Bayern

Frage zu Float-Werten

Beitrag von dllfreak2001 »

Also es ist kein wirkliches Problem nur es scheint sehr merkwürdig zu sein. Wie man an meinem Kollisiongebastel für ein Jump&Run sieht erzeugt PB bei den Floatvariablen paar Stellen hinter dem Komma ungenauigkeiten bzw. Fehler(bin mir nicht sicher ob das ein Fehler ist).
Wie kommt es zu diesen Fehlerstellen?

Code: Alles auswählen

InitSprite()
InitKeyboard()

OpenScreen(800,600,32,"J&R-Kollision v2.0")

;Spielerboxposition
Global boxx.f
Global boxy.f
;Alte Spielerposition
Global olposx.f
Global olposy.f
;Kollisionstyp auf X/Y
Global coltypex.l
Global coltypey.l
;Fallgeschwindigkeit
Global fallspeed.f
;Kollision allgemein
Global switch.b

boxx = 200
boxy = 200
fallspeed = 4.0

;-Hauptschleife
Repeat
ExamineKeyboard()


If KeyboardPushed(#PB_Key_left) ;Nach Links laufen
 boxx - 2.1 
  If boxx < 0 
   boxx = 0 
  EndIf
EndIf

If KeyboardPushed(#PB_Key_right) ;Nach Rechts laufen
 boxx + 2.1
  If boxx > 784 
   boxx = 784 
  EndIf
EndIf

If KeyboardPushed(#PB_Key_up) ;Springen
 fallspeed = -2.0
EndIf


If fallspeed < 4.0 ;damit fallspeed auch wieder auf den standart-Wert zurückkehrt 
 fallspeed + 0 .1
EndIf

boxy + fallspeed ;fallspeed auf boxy aufaddieren damit eine Art von Schwerkraft besteht

;Damit die Spielerbox nixht aus dem Bild wandern kann

If boxy < 0 
 boxy = 0 
EndIf

If boxy > 468
 boxy = 468 
EndIf


;-Kollisionsroutine

If boxx > 352 And boxx < 416 And boxy > 252 And boxy < 316 ;Abfrage ob die Spielerbox überhaupt mit der Kollisionsbox kollidiert

 If olposx =< 352 ;Kollision von links
  boxx = 352
  coltypex = 1
 EndIf
 
 If olposx => 416 ;Kollision von rechts
  boxx = 416
  coltypex = 2
 EndIf
 
 If olposy =< 252 ;Kollision von oben
  boxy = 252
  coltypey = 1
 EndIf

 If olposy => 316 ;Kollision von unten
  boxy = 316
  coltypey = 2
  fallspeed = 4.0 ;Wenn die Box von unten kollidiert dann geht der Fallspeed sofort auf standart
 EndIf

switch = 1 ;Kollision algemein

Else
 ;Zurücksetzen der Kollision und der Typen
 switch = 0 
 coltypex = 0
 coltypey = 0
EndIf


; Generieren der Alten Koordinaten der Spielerbox für die Kolisionstypenbestimmung 
olposx = boxx
olposy = boxy


;-Grafische Ausgabe
StartDrawing(ScreenOutput())

 Box(boxx,boxy,32,32,RGB(154,255,101)) ; Die Spieler Box

 Box(0,500,800,100,RGB(0,0,0)); Der Boden

 If switch = 0
   Box(384,284,32,32,RGB(255,255,0)) ; Kollisionsbox ohne Kollision
  Else
   Box(384,284,32,32,RGB(255,0,0))   ; Kollisionsbox mit Kollision
 EndIf

 ;Ausgabe der Variablen
 DrawingMode(1)
 FrontColor(255,255,255)
 
  Locate(0,0)
 DrawText("boxx = "+StrF(boxx,8))
  Locate(0,16)
 DrawText("boxy = "+StrF(boxy,8))
  Locate(0,32)
 DrawText("olposx = "+StrF(olposx,8))
  Locate(0,48)
 DrawText("olposy = "+StrF(olposy,8))
  Locate(0,64)
 DrawText("collision = "+Str(switch))
  Locate(0,80)
 DrawText("coltypex = "+Str(coltypex))
  Locate(0,96)
 DrawText("coltypey = "+Str(coltypey))

StopDrawing()

;-Auf Bildschrim darstellen und löschen des Buffers
FlipBuffers()
ClearScreen(10,30,100)

Until KeyboardPushed(#PB_Key_Escape) ;Aus die Maus
CloseScreen()
End ;Schluß mit lustig
I´a dllfreak2001
THEEX
Beiträge: 804
Registriert: 07.09.2004 03:13

Beitrag von THEEX »

Ich hab mir Dein Programm jetzt nicht angeschaut, aber die Ungenauigkeit hat bestimmt damit zu tun:
Spezielle Informationen über Fließkommazahlen (Floats)

Eine Fließkomma-Zahl (auch Gleitkomma-Zahl, englisch: Floating Point Number) wird in einer Art und Weise gespeichert, die den Binär-Punkt (trennt "Ganzzahlteil" vom "Kommateil") innerhalb der Zahl "gleiten" lässt, wodurch das Speichern sehr großer aber auch sehr kleiner Zahlen (mit vielen Nachkommastellen) möglich wird. Wie auch immer, Sie können nicht sehr große Zahlen mit gleichzeitig sehr hoher Genauigkeit (sozusagen große und kleine Zahlen zur selben Zeit) speichern. Eine weitere Einschränkung von Fließkomma-Zahlen ist, dass sie stets im Binärmodus arbeiten, weshalb sie nur die Zahlen exakt speichern können, welche mittels Multiplikation oder Division mit 2 ermittelt werden können. Dies ist insbesondere wichtig zu wissen, wenn Sie versuchen, eine Fließkommazahl in einer visuell lesbaren Form darzustellen (oder mit ihr Rechenoperationen auszuführen) - das Speichern von Zahlen wie 0.5 oder 0.125 ist einfach, da sie Divisionen von 2 sind. Das Speichern von Zahlen wie 0.1 ist schwieriger, diese wird möglicherweise als Zahl 0.9996125 gespeichert. Sie können versuchen, nur eine begrenzte Anzahl an (Nachkomma-) Stellen darzustellen, seien Sie aber nicht überrascht, wenn die Darstellung der Zahl anders aussieht, als Sie dies erwarten!
Dies gilt für alle Fließkomma-Zahlen, nicht nur die in PureBasic.
Auszug aus der Hilfe...
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

Beitrag von freedimension »

*argh* es dauert bestimmt nicht mehr lange bis ich allergisch auf die Frage reagiere (oder ist dieses Posting schon ein erstes Symptom???).

Nicht persönlich nehmen, aber dafür gibt es wirklich die Suchmaschine (notfalls auch die des alten Forums). Desweiteren soll es tatsächlich helfen ab und an mal die Hilfe durchzulesen (bevor Ich persönlich ein Programm überhaupt installiere lese ich mir grundsätzlich die Hilfe komplett durch, und wenn ich jede Seite nur überfliege).
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

etwas was die hilfe imho nicht genug verdeutlicht ist, dass das eine einschränkung der fpu auf x86ger prozessoren ist, keine einschränkung von purebasic. bei ppc prozessoren und sparcs ist es aber iirc genauso.

darum testet man floats !!!NIE!!! auf gleichheit, sondern immer auf einen bereich.
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

Hi :) ,

Eine alternative zum float wert währe, das man jede zahl im normalen zahlensystem (0...10) zu 4 Bit umrechnet, zum beispiel bei den einerpotenzen, das selbe macht man für die zehnerpotenz , hunderter, tausender, ..... Und das gleiche verfahren kann auchin den anderen zahlenbereich gehen (0 .... - unendlich).

Nachteil: Das rechnen dauert lange.

Beispiel: Bei 10 hoch 10 sind es: 5 Byte (10 x 0.5).
wenn die zahl z.b.: durch 2 dividiert wird, wird die ersthöchste zahl /2 geteilt (5) und die zweite durch 2 (0 bleibt null) und so weiter und so fort !

Für fragen bin ich offen...

Grüße: Robert
Jeder hat einen Schutzengel.
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

Das hier ist ein forgeschlagener rechenweg, mit einer (sau) hohen präzision und unendlichen zahlenraum (das ist meine Erfindung).

Noch ein Beispiel zum besseren verständnis:
:)
Man hat die zahl 12345,6789

halbbyte -4 hat die 9 dh: 1001
halbbyte -3 hat die 8 dh: 1000
Halbbyte -2 hat die 7 dh: 0111
Halbbyte -1 hat die 6 dh: 0110

HalbByte +1 hat die 5 dh: 0101
halbByte +2 hat die 4 dh: 0100
halbByte +3 hat die 3 dh: 0011
halbByte +4 hat die 2 dh: 0010
halbbyte +5 hat die 1 dh: 0001

variablenwerte:
plus = 5 (weil es fünf stellen vor dem komma giebt,
minus = 4 (weil es fier stellen nach dem komma giebt)

Bytewerte (zb.: zum abspeicher als datei):

1 Byte : plus
2 Byte : minus
3 Byte : plus (hier 1) | plus (hier 2)
4 Byte : plus (hier 3) | plus (hier 4)
5 Byte : plus (hier 5)
6 Byte : minus (hier 6) | minus (hier 7)
7 Byte : minus (hier 8 ) | minus (hier 9)
......

Strukturenwerte (linked list):

mos ; wenn 0 --> negative zahl
;wenn 1 --> Positive zahl
mod ; modus wenn 0 --> negativ (der zahl)
; wenn 1 --> positiv
zahl ;die eigentliche zahl ( 0 ... 9)
pointer.l ;der verweiser auf die nächsthöhere Zahl


Berechnung(theorie):
na so, wie wir's in der schule gelernt haben :lol: :lol:

lasst euch weiter überraschen, bald giebts ne zugabe !

Grüße ... Robert
Danke
Jeder hat einen Schutzengel.
Benutzeravatar
Sylvia
verheiratet<br>1. PureGolf-Gewinner
Beiträge: 487
Registriert: 29.08.2004 09:42
Wohnort: Old Europe

Beitrag von Sylvia »

Es ist mir um diese Uhrzeit noch etwas zu früh, deine Gedankengänge
hier im Detail nachzuvollziehen;...das Ganze erinnert mich aber SEHR
stark an BCD...!
Basic Pur = PureBasic
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

Beitrag von freedimension »

Robert Wünsche hat geschrieben:(das ist meine Erfindung)
:roll:
Mit ein wenig Recherche kommst du ganz einfach auf BCD und APM.


Wie gesagt, auch ich dachte mit 13/14 ich wär der King :roll: Aber mach dir nix draus, ist in der Pubertät gängiges Verhalten :D
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

ach ja,
(stimmt),
ich war aber als "erster" auf die idee gekommen, das in PB einzusetzen !
Jeder hat einen Schutzengel.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8820
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

:lol:
Ich glaube bisher waren schon mehrere hier im Forum, die sowas machen wollten und auch gemacht habe. Sogar ich war dabei. /:->
Antworten