Seite 1 von 2
Casten von Float auf Long auch bei Vergleichen?!
Verfasst: 13.02.2008 23:43
von ZeHa
Das versteh ich jetzt echt nicht
Ich habe folgenden Vergleich:
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!!
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)?
Verfasst: 13.02.2008 23:45
von ZeHa
Hab grad den Debugger deaktiviert, aber auch dann tritt genau das gleiche Phänomen auf...
Re: Casten von Float auf Long auch bei Vergleichen?!
Verfasst: 13.02.2008 23:54
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:
So funktioniert es...

Verfasst: 13.02.2008 23:56
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 :
da im normalfall mit LONGs gerechnet wird entsteht beim 1. 0*100=0 und beim 2. halt nicht weil 4000/100 eben 40 ist
Verfasst: 14.02.2008 00:07
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.
Verfasst: 14.02.2008 00:09
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

Verfasst: 14.02.2008 01:01
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.

Verfasst: 14.02.2008 13:49
von ZeHa
Hmm nee ich glaub Dir das

sonst würd's ja auch funktionieren

Verfasst: 14.02.2008 14:09
von #NULL
das finde ich aber auch ein dolles stück

Verfasst: 14.02.2008 21:09
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.