Seite 1 von 1

Konvertierung von Variablentypen ...

Verfasst: 06.02.2006 11:07
von helpy

Code: Alles auswählen

Debug "Convert floating point constant to b,w,l,q"
#TEST = 1.55
b.b = #TEST
w.w = #TEST
l.l = #TEST
q.q = #TEST

Debug b
Debug w
Debug l
Debug q
; RESULT is 1


Debug "Convert single floating point variable to b,w,l,q"
f.f = #TEST
b=f
w=f
l=f
q=f

Debug b
Debug w
Debug l
Debug q
; RESULT is 2


Debug "Convert double floating point variable to b,w,l,q"
d.d = #TEST
b=d
w=d
l=d
q=d

Debug b
Debug w
Debug l
Debug q
; RESULT is 2
Warum der Unterschied? (ist übrigens in 3.94 genauso, natürlich mit Ausnahme der *.q und *.d)

cu, helpy

Verfasst: 06.02.2006 17:50
von Toshy
Ich habe den Code nur mal erweitert, damit man genauer sieht "wo" "was" geschieht.

Code: Alles auswählen


Debug "Convert floating point constant to b,w,l,q" 
#TEST = 1.55 
f.f = #TEST
b.b = #TEST 
w.w = #TEST 
l.l = #TEST 
q.q = #TEST 

Debug #TEST
Debug f
Debug b 
Debug w 
Debug l 
Debug q 
; RESULT is 1 


Debug "Convert single floating point variable to b,w,l,q" 
f = #TEST 
b=f 
w=f 
l=f 
q=f 

Debug f
Debug b 
Debug w 
Debug l 
Debug q 
; RESULT is 2 


Debug "Convert double floating point variable to b,w,l,q" 
d.d = #TEST 
f=d
b=d 
w=d 
l=d 
q=d 

Debug d
Debug f
Debug b 
Debug w 
Debug l 
Debug q 
; RESULT is 2
eine 100%ige Antwort kann ich dir auch nicht geben, aber folgendes, falls du es eh nicht schon weißt. Floats arbeiten ganz anders als andere Variablentypen, auch bitweise gesehen. Man kann zwar ein Float in einem Long speichern, aber nicht damit rechnen (einfach mit Poke kopieren). Außerdem sind Floats wie du ja weißt Decimalzahlen und diese kann ein ander Typ nicht aufnehmen. Es wird also umgewandelt und daher sind deine Abschnitte II un III richtig. Weshalb nun Abschnitt I anders ist, kann ich nicht ganau sagen, nur vermuten. Wie man sieht wird die Umwandlung in einen Float korrekt übernommen, in Bytes usw. "nicht". Aber ich vermute, das dies daran liegt, das #TEST KEIN FLOAT ist, sondern Konstanten. Und es kann und wird sein, das die änders behandelt werden. Ich "vermute" das konstanten ähniche einem "String" gespeichert werde, also eine andere "markierung" haben. Dadurch könnte es zu unterschieden kommen. eine Umwandlung eines "Zahlenstrings" in eine Zahl arbeitet unterschiedlich (str() und strf()).
Vermutlich wird zum Umwandeln von einer Konstante in einen FLoat die FPU (heißt doch glaube ich so) genutz und weil ein "Float" mit dabei ist dies als Dezimalzahl genommen. Bei anderen Arten wird vielleicht einfach davon ausgegangen Ziel ist "keine Decimalzahl" und dir FPU nicht genutzt und dann gleibt zum Umwandeln nur die möglichkeit den "Vorkommawert" durch "kopieren" zu übernehmen. Ist wie gesagt nur so ne Vermutung.
man könnte da sicher noch was intern ändern.

[edit]
habe mal ein bissl getest.
Ich habe int() und b2.b = Round(#TEST, 1) getestet.
bei round() im Modus 1 gibt es ne 2 Zurück. Das bedeutet dann wohl einfach, das Konstanten standartmäßig abgerundet werden. Fragt sich jetzt nur, ob das ein Versehen ist oder absichtlich so gemacht, weil Konstanten eher wie Strings behandelt werden.

t.s = "1.55"
Debug Val(t)
Debug ValF(t)
liefern auch unterschiedliche ergebnisse. Strings also werden bei der Umwandlung abgerundet, Konstanten auch.

Verfasst: 06.02.2006 18:56
von Nik
DSie Varaiblenkonvertierungen der neuen Typen sind noch etwas Buggy aber laut englischem Forum ist Fred bereits daran das Propblem zu suchen....

Verfasst: 06.02.2006 19:07
von Toshy
laut helpy hat das damit nichts zu tun, es liegt nur daran wie profan arbeitet. aber wenn ich mich recht erinnere ist das nicht nur in PB so.

Verfasst: 06.02.2006 22:58
von NicTheQuick
Wenn man einer Integer-Variable eine Konstante mit Fließkommawert
zuweist, ist das nichts anderes, als wenn man diesen Wert direkt dorthin
schreibt, wo man die Konstante einsetzt.

Der PB-Compiler geht Zeile für Zeile durch und speichert alle Konstanten,
die ihm so über den Weg laufen in einer Liste. Wenn nun irgendwo eine
dieser Konstanten benutzt wird, macht er so, als ob statt dieser Konstante
der Wert steht, den die Konstante besitzt. Und wenn eine
Fließkommakonstante einer Integervariablen zugewiesen wird, dann
schneidet der Compiler den Nachkommateil ab und weist dem Integer nur
den ganzzahligen Wert der Konstanten zu.

Beim Kompilierprozess geht es also anders vor sich als bei der
Programmausführung. Während dem Kompilieren spielt die FPU noch
keine Rolle bei der Typumwandlung, das macht nämlich nur der
Kompilier. Wird einer Integervariablen allerdings eine Fließkommavariable
zugewiesen, ist das eine Typumwandlung während der Programmlaufzeit
und die FPU übernimmt das und rundet korrekt.

Ich hoffe die Erklärung war einleuchtend.

Verfasst: 06.02.2006 23:26
von Toshy
Klingt logisch und hattest mich überzeugt, jetzt aber denke ich es ist anders.

Es wäre also so, also im dort im Maschinecode also nach dem compilieren
long.l = 1 (natürlich in Form von Maschinencode) steht. das ist aber nicht so.
es steht wohl doch eher long.l=1.55 dort, denn ansonsten kann ich mir das nicht so ganz erklären bzw. kann es mir erklären finde folgendes aber komisch:
Ergebnis.l = 1.55
Debug Ergebnis
--> AUsgabe gleich "1"
a.l = 1
Ergebnis.l = 1.55 + 1
Debug Ergebnis
--> Ausgabe gleich "3" (nicht 2)
+ 0 ergibt dann 2 und nicht auch 1.

Das wird wohl auch korrekt sein, ist aber doch nicht so toll.
habe ich also im Code (wei bei mir) lauter konstanten für bestimmte dinge hänge ich wenn dieser natürlich kein + 0 an, aber ein + 1 wenn es nötig ist. und man darf doch dann davon ausgehen, das in diesem fall der unterschied bei selbem konstanteninhalt der selbe ist (mit unterschied der "+differenz"). dem ist dann aber nicht so.
ich rätsele bei mir eh schon seit einiger zeit weshalb ich hin und wieder mal nen fehler bei konstanten + werten habe. ich glaube jetzt weiß ich wonach ich suchen muß.

Verfasst: 06.02.2006 23:36
von NicTheQuick
Das ist auch logisch zu erklären.
Wenn einer Ganzzahlvariablen ein zusammengesetzter Wert aus
mindestens einer Fließkommavariablen oder -konstanten übergeben wird,
dann werden diese beiden Werte während der Programmausführung in
der FPU verrechnet und nicht schon während dem kompilieren.

Dahingehend könnte PB also noch etwas während dem Kompilieren
optimieren. Dann würde auch [c]long.l = 1.55 + 1[/c] gleich [c]2[/c] ergeben.

Verfasst: 06.02.2006 23:38
von Eric
Ergebnis.l = 1.55
Ein Long kann keine Fließkommazahlen aufnehmen, und deshalb konvertiert
der Compiler das 1.55 zu einer Ganzzahl.
Und anscheinend rundet der Compiler hier ab.
Ergebnis.l = 1.55 + 1
Debug Ergebnis
--> Ausgabe gleich "3" (nicht 2)
+ 0 ergibt dann 2 und nicht auch 1.
Hier wird aufgerundet.
1. Entweder ist der Compiler sehr eigensinnig, was das Auf- und Abrunden
angeht
2. Oder der Compiler optimiert das nicht, sondern überlässt die Konvertierung
der FPU (und das wäre dann wärend der Programmausführung, und nicht
wärend dem Kompilieren)

Edit:
Verdammt, Nic war schneller
du solltest mir mehr Zeit zum Antworten lassen :mrgreen: