Addition + Rundung
-
Hallo,
ich möchte zwei Double-Zahlen addieren mit Rundung nach oben.
pushl %ebp
movl %esp, %ebp
fnstcw -16(%ebp)
fnstcw -8(%ebp)
orw $0x0800, -8(%ebp)
fldcw -8(%ebp)
fldl 8(%ebp)
faddl 16(%ebp)
fldcw -16(%ebp)
movl %ebp, %esp
popl %ebpAber er rundet nicht nach oben. Wo liegt denn der Fehler?
Gruß
Boris
-
Ok, ich habe den Fehler gefunden, er liegt in folgender Zeile:
fldcw -16(%ebp)
Nur sehe ich den Fehler nicht. So bald ich diese Zeile ausführen lassen,
ist das Ergebnis falsch, aber warum???
-
es finden zwei rundungen statt - die erste bei der addition. die zweite dann wenn das ergebnis dann in einem double gespeichert wird - das findet aber erst nach dem assembler teil statt - wenn das controlwort zurückgestzt wurde.
eine lösung ist, auf das rücksetzen zu verzichten - zum setzen des controlworts muss man ohnehin keinen assembler bemühen. die andere ist, die umwandlung in ein double durch ein fstp/fld paar zu forcieren (bevor das controlwort zurückgesetzt wird) - das kostet nicht übermässig viel zeit, ist im grunde dasselbe, was -ffloat-store auch tut.
nebenbei bemerkt, ist das lokale ändern des controlworts auf etwas anderes als round_nearest oder chop extrem unperformant (generell umschalten zwischen mehr als 2 verschiedenen werten, und diese beiden sind diejenigen, die der compiler sowieso benutzt, einmal fürs normale rechnen, das andere wenn in ints gewandelt wird). rechne mit ~150takten/fldcw auf einem P4. beim athlon ist es auch nicht viel besser.