Casten von Float auf Long auch bei Vergleichen?!

Hier werden, insbesondere in den Beta-Phasen, Bugmeldungen gepostet. Das offizielle BugForum ist allerdings hier.
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Casten von Float auf Long auch bei Vergleichen?!

Beitrag von ZeHa »

Das versteh ich jetzt echt nicht :freak:

Ich habe folgenden Vergleich:

Code: Alles auswählen

If distance < (#TILE_HEIGHT * 0.5)
Meine bisherige Programmiererfahrung sagt mir eigentlich folgendes:
1) #TILE_HEIGHT wird mit 0.5 zur Compile-Zeit (!) multipliziert
2) der Vergleich heißt nun (da #TILE_HEIGHT bei mir 64 ist): If distance < 32
3) wenn distance kleiner als 32 ist, muß der Vergleich "true" zurückgeben.

Leider passiert das so nicht. In der Tat passiert scheinbar folgendes:
1) distance ist ein Long
2) alles, was auf der rechten Seite steht, wird daher als Long gecastet
3) die Multiplikation auf der rechten Seite ergibt folglich 0
4) wenn distance kleiner als 32 ist, heißt das noch lange nicht, daß der Vergleich "true" zurückgibt.

Das ist doch echt kaum zu fassen. Daß von rechts nach links gecastet wird, war mir klar, aber erstens wird sowas doch normalerweise für jede Seite separat gemacht und nicht für den gesamten Vergleich, und zweitens muß doch die rechte Seite zur Laufzeit bereits den konstanten Wert 32 beinhalten.

Ach ja - wenn ich distance vorher als Float deklariere, läuft es!! :o
Ich versteh das einfach nicht... was ist da los? Hab ich irgendwas übersehen? Oder ist das ein Bug in PB (der mir vorher noch nie untergekommen ist)?
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Hab grad den Debugger deaktiviert, aber auch dann tritt genau das gleiche Phänomen auf...
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Re: Casten von Float auf Long auch bei Vergleichen?!

Beitrag von milan1612 »

ZeHa hat geschrieben: 1) #TILE_HEIGHT wird mit 0.5 zur Compile-Zeit (!) multipliziert
So weit ich weiß stimmt das nicht, die Konstante wird zur Compile-Zeit nur
durch den Wert ersetzt, die Multiplikation wird zur Laufzeit durchgeführt.
Zu deinem Problem hab ich allerdings keine Ahnung...

*Edit:

Code: Alles auswählen

If distance < Int((#TILE_HEIGHT * 0.5))
So funktioniert es... /:->
Zuletzt geändert von milan1612 am 13.02.2008 23:57, insgesamt 1-mal geändert.
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

das liegt doch an der *0.5 daduch verursachst du dieses Problem.

Lösung :

Code: Alles auswählen

distance = 15
#TILE_HEIGHT = 32

If distance < (#TILE_HEIGHT / 2)
 Debug #True
EndIf
dadurch wird auf beiden Seiten mit LONGs gerechnet und es tritt kein Missverständnis auf, oder du musst halt beides FLOAT machen

Aber Floats mit Long zu vergleich würde ich generell vermeiden

Ein änlicher Fall ist dieser :

Code: Alles auswählen

Wert = 40

Debug Wert/100*100
Debug Wert*100/100
da im normalfall mit LONGs gerechnet wird entsteht beim 1. 0*100=0 und beim 2. halt nicht weil 4000/100 eben 40 ist
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

1) Ich meine aber gelesen zu haben, daß mehrere Konstanten, egal ob sie als Alias oder als direkter Wert drinstehen, bereits beim Compilen zusammengefaßt werden... daher erwarte ich eigentlich direkt die 32 und nicht 64 * 0.5

2) wenn ich Debug 64 * 0.5 mache, erhalte ich ebenfalls 30.0 und nicht 0, weil der Compiler erkennt, daß eine Float an der Multiplikation beteiligt ist.

3) Floats mit Long vergleichen kann auf Gleichheit (und Ungleichheit) ziemlich problematisch werden, aber wenn ich auf größer/kleiner vergleiche, ist das in den meisten Fällen kein Problem.

4) Natürlich kann ich auch / 2 machen, aber in meinem Fall ist es vom Code her logischer, mit Kommazahlen zu arbeiten. Aber was alleine funktioniert, darf meiner Meinung nach nicht von dem abhängen, was auf der linken Seite steht, da normalerweise erstmal jeder Ausdruck separat ausgewertet wird (sprich links steht distance, das ist bereits fertig, rechts wird multipliziert, und zwar so wie bei 2)), und erst hinterher verglichen wird.
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Hier mal noch der Direktvergleich:

Code: Alles auswählen

distance.l = 10

If distance < 64 * 0.5
    Debug "kleiner"
Else
    Debug "groesser"
EndIf
PureBasic gibt "groesser" aus.

Code: Alles auswählen

#include <stdio.h>

int main()
{
    int distance = 10;
    
    if (distance < 64 * 0.5f)
        printf("kleiner");
    else
        printf("groesser");
    
    return 0;
}
C gibt "kleiner" aus.



EDIT: Wenn man bei der PureBasic-Version nun aber aus distance.l ein distance.f macht, geht es plötzlich, was beweist, daß die Ausdrücke auf der rechten Seite auf den Typ des Ausdrucks auf der linken Seite gecastet werden. Mir persönlich erscheint das ziemlich unsinnig, da die Zeile normalerweise per Baumstruktur geparst wird und somit der rechte Ausdruck bereits ausgewertet sein sollte, bevor überhaupt der Vergleich durchgeführt wird. Daher ist das für mich entweder ein Bug oder eine Unüberlegtheit, und zwar solange, bis mir einer einen Gegenbeweis bzw. einen Sinn vermitteln kann :mrgreen:
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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 »

Soviel ich weiß, hat sich Fred nie mit dem Compilerbau auseinandergesetzt,
sondern einfach drauflos gecodet. Daher vielleicht die Ungereimtheiten.

Falls ich jetzt was falsches sage, bitte zuschlagen. :mrgreen:
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Hmm nee ich glaub Dir das ;) sonst würd's ja auch funktionieren ;)
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

das finde ich aber auch ein dolles stück :mrgreen:
my pb stuff..
Bild..jedenfalls war das mal so.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

yo, das is orginol en käfer....

dass PB mit seinem typecasting manchmal abenteuerliche ergebnisse bringt,
is ja zu genüge bekannt, aber dies hier ist echt ein dicker hund.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten