Autor Beitrag
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 21.05.06 14:19 
Kann ist den Befehlen FISTP (FPU) bzw. CVTSS2SI (SSE) irgendwie beibringen, bei 0.5 richtig aufzurunden? Normalerweise wird 0.5 nämlich auf 0 gerundet.
Waldteufel
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 21.05.06 17:26 
Hi Spaceguide. :wave:

Guck dir einfach in der Unit Math bei der Funktion SetRoundMode ab, was die bei SetRoundMode(rmNearest); macht. ;-)

(Hast ja laut Profil die Prof-Version, bei der sind ja die Quellen dabei)
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 21.05.06 17:47 
Das hatte ich schon untersucht. Standard ist rmNearest. Ist der ganzzzahlige Teil gerade (0.5,2.5,4.5 ...), so wird immer abgerundet, ist er ungerade (1.5,3.5,5.5 ...), dann aufgerundet.
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: So 21.05.06 18:27 
Hey,

notfalls könntest du dir auch einen eigene Funtkion schreiben.
Ich habe mal eine geschrieben, die dir hoffentlich weiterhelfen mag ;):

Sie Rundet bei >= 0,5 auf und bei < 0,5 ab:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function Round(Number: Real): Real;
var FindC: Byte;
    NumAsStr: String;
begin
 FindC := pos(',',FloatToStr(Number));

 if FindC = 0 then
  Result := Number
   else
    begin
     NumAsStr := Copy(FloatToStr(Number),FindC,Length(FloatToStr(Number))-FindC+1);
      If StrToFloat(NumAsStr) >= 0.5 then
       begin
        NumAsStr := FloatToStr(Number);
        Delete(NumAsStr,FindC+1,Length(FloatToStr((Number)-FindC)));
        Result := StrToFloat(NumAsStr)+1;
       end else
        Result := RoundTo(Number,0);
      end;
end;


mfg
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 21.05.06 18:42 
Sehr performant ...
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: So 21.05.06 18:48 
War nur ein Vorschlag ;)
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 21.05.06 18:51 
Bei näherem Hinsehen muss ich aber lachen. Ein einfaches Trunc(x+0.5) macht prinzipiell das gleiche, nur eben korrekt: Deine Funktion funktioniert nur, wenn der Separator ein Komma ist (bei englischen Systemen ist es ein Punkt) und -0.5 rundet sie zu +1!
starsurfer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 334

Win 95, Win 98, Win XP, Win Vista, Linux
D5 Enterprise ,D2005, D6 Personal, Visual C++ Express 2005, C++ Builder 6 E, Dev-C++
BeitragVerfasst: So 21.05.06 18:54 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function RountByFive(valve:real):integer;
var help:integer;
begin
result:=trunc(valve);
help:=trunc(frac(valve)*10));
if help>4 then inc(Result);
end;


das is dürfte auch gehen :D

und es ist ein bisschen schneller als der vorherige Vorschlag

//Edit, ok du hast ja deine Lösung schon ^^

_________________
GEIZ IST GEIL! - Ihr Sozialamt


Zuletzt bearbeitet von starsurfer am So 21.05.06 18:55, insgesamt 1-mal bearbeitet
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: So 21.05.06 18:55 
:oops: Du hast recht.
Ich sitze hier einfach schon zu lange am PC und bin vollkommen übermüded.
Ich denk, ich leg mich gleich mal hin.

Und nun back zum Topic.

Mfg ;)
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 21.05.06 18:57 
Ich find das jetzt nicht fair. Ich habe eine ernste Frage gestellt und werde nur verarscht.
Green
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 283

Windows XP Home
Delphi 6 Enterprise
BeitragVerfasst: So 21.05.06 19:01 
wieso das denn?? hast doch deine frage schon selber beantwortet...
und du hast sogar zwei weitere varianten ;)
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 21.05.06 19:18 
So? Meine Frage lautete aber nicht, wie ich eine Zahl korrekt runden kann, sonder:

"Kann ist den Befehlen FISTP (FPU) bzw. CVTSS2SI (SSE) irgendwie beibringen, bei 0.5 richtig aufzurunden? Normalerweise wird 0.5 nämlich auf 0 gerundet."
Green
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 283

Windows XP Home
Delphi 6 Enterprise
BeitragVerfasst: So 21.05.06 19:25 
nunja, eine Funktion kann man so einfach nicht ändern, ausserdem warum denn nicht eine eigene verwenden?
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 21.05.06 19:29 
Weil es performanzkritisch ist.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 21.05.06 20:46 
Das ist leider Architektur-Bedingt nicht möglich ...

Du kannst aber

ausblenden Delphi-Quelltext
1:
2:
3:
4:
asm
    FADD    [OneHalf]
    FRNDINT
end;


versuchen, wenn Du das Rounding Control-Flag auf Truncate gesetzt hast.

Die FPU unterstützt nur RoundUp, RoundDown, BankersRounding und Truncate als Modi. Das mathematisch korrekte Runden muss man emulieren.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Mo 22.05.06 20:49 
Hi,
also mit SetRoundMode(rmDown) bekomme ich Round(x) = Trunc(x+0.5) korrekt hin. Nur bin ich mir ein bisschen unsicher, ob das Control-Word auch so bleibt. Gibt es irgendwelche Komponenten, die gerne mal das Control-Word ändern und nicht mehr zurücksetzen?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 22.05.06 21:29 
Wäre mir innerhalb der VCL nichts bewusst. Trunc und Round aus der RTL sind deshalb so lahmarschig, weil sie das CW immer erst wieder Resetten... Dadurch geht enorm Zeit verloren ...

Ansonsten setz einfach einmal vor Ausführung deiner Zeitkritischen Aktionen das CW ... Innerhalb deiner Routine kannst Du dann ggf. an kritischen Stellen noch mal kurz eine Überprüfung einbauen, sollte dies nötig sein ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Di 23.05.06 12:13 
Gibt's für die SSE-Einheit auch sowas wie einen Rounding Mode?
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Di 23.05.06 13:13 
OK, wenn ich die Bits 14/13 des Registers MXCSR mittels LDMXCSR auf 01 setze, bekomme ich auch die SSE-Einheit dazu, immer abzurunden, jedoch scheint irgendetwas das Register wieder zurückzusetzen, so dass ich das Register immer wieder vor jeder Rundungsaktion setzen muss. Irgendwelche Hinweise, was es zurücksetzt?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 23.05.06 14:18 
Wüsste ich jetzt aus dem Kopf nix... Hab mit SSE noch nicht gearbeitet. Könnte aber sein, dass durch das Neueinrichten der SSE-Umgebung das Flag resettet wird? FPU und SSE sharen sich ja die Register-Speicher ...

Oder meinst Du das Flag wird bei jedem Befehl resettet ... Dann kannst Du glaube nicht viel tun ...???

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.