2012-06-10 6 views
8

Ich versuche Delphi zu runden wie Excel, aber ich kann nicht. Hier ist der Code:Wie bekomme ich Delphi Currency Type, um die ganze Zeit wie Excel zu runden?

procedure TForm1.Button1Click(Sender: TObject); 
var 
s : string; 
c : currency; 
begin 
c := 54321.245; 
s := ''; 
s := s + Format('Variable: %m',[c]); 
s := s + chr(13); 
s := s + Format(' Literal: %m',[54321.245]); 
ShowMessage(s); 
end; 

Delphi Rounding

ich eine Währung Variable bin mit, die auf 54.321,245 gesetzt ist, und wenn ich formatiert diese Variable rundet mit Bankers Runden. Wenn ich jedoch den gleichen Wert wie ein Literal formatiere, rundet es den Excel-Runden-Modus ab.

Ich habe erwartet, dass dies auf $ 54,321.25 rundet, ob es sich um eine Währungsvariable oder einen Literalwert handelt. Wie kann ich sicherstellen, dass Delphi jedes Mal die gleiche Weise wie Excel ausführt?

bearbeiten

The rounding I expect to see is as follows: 
54,321.245 = 54,321.25 
54,321.2449 = 54,321.24 
54,431.2499 = 54,421.25 

ich nur Literale verwende die verschiedenen Möglichkeiten Delphi rundet zu zeigen. Ich erwarte, Variablen im eigentlichen Code zu verwenden.

Hinweis:
Wenn ich die Variable aus Währung zu es richtig verlängert ändern rundet

Edit # 2

Einige haben vorgeschlagen, dass ich nicht über eine Klares Verständnis meiner Anforderungen, das ist absolut nicht wahr. Ich habe ein klares Verständnis für meine Anforderungen, und ich bin offensichtlich nicht sehr gut darin, sie zu erklären. Die gewünschte Rundungsmethode ist zwei Dezimalstellen. Wenn der Dezimal-Teil einen Tausendstel-Wert> = 0,005 hat, möchte ich, dass er auf 0,01 gerundet wird. Der von Delphi angebotene Währungstyp tut das nicht. Ich habe dieses Beispiel auch mit Microsoft SQL mit einem Geld-Datentyp versucht (von dem ich annahm, dass es mit der Währung von Delphi identisch war) und SQL rundet seinen Geld-Typ so ab, wie ich es beschrieben habe.

  • SQL Geld> = 0,005 = 0,01
  • Delphi Währung> = 0,005: = 0,00

Edit # 3
Gut Artikel: http://rvelthuis.de/articles/articles-floats.html
Mögliche Lösung: http://rvelthuis.de/programs/decimals.html

Bearbeiten # 4
0 Hierist eine der Lösungen von Embarcadero Diskussion

function RoundCurrency(const Value: Currency): Currency; 
var 
    V64: Int64 absolute Result; 
    Decimals: Integer; 
begin 
    Result := Value; 
    Decimals := V64 mod 100; 
    Dec(V64, Decimals); 
    case Decimals of 
    -99 .. -50 : Dec(V64, 100); 
    50 .. 99 : Inc(V64, 100); 
    end; 
end;
+1

Sind Sie sicher, dass Excel 100% konsistent ist in allen seinen APIs und Funktionen in Runden? –

+0

@Warren - Nein, ich bin mir nicht 100% sicher. Ich verkaufe Finanzanwendungen und muss sicherstellen, dass meine Zahlen mit denen von Excel übereinstimmen. –

+2

Um diese Frage richtig zu beantworten, müssen Sie uns wirklich sagen, welche Art von Rundung Sie erwarten. –

Antwort

12

Wenn ich Sie richtig verstehe, sind Sie für diese suchen:

function RoundTo2dp(Value: Currency): Currency; 
begin 
    Result := Trunc(Value*100+IfThen(Value>0, 0.5, -0.5))/100; 
end; 
+0

Soweit ich bisher gelesen habe, kann ich sagen, dass die Verwendung der FPU beim Umgang mit Währungen nicht empfohlen wird. Es kann Probleme beim Runden von Rundungen verursachen. Es gibt Lösungen in dem Thread, den ich verknüpfe, die dies vermeiden oder es mit großer Sorgfalt tun. –

+1

+1 Schön gemacht ... Du bist von einem anderen Planeten David. –

+0

@SertacAkyuz Worauf fahren Sie? Arithmetik in Währung nutzt FPU, denke ich. –

0

Sie Kontrolle darüber, wie delphi Runden Zahlen gewinnen können:

uses Math; 
... 

procedure TForm1.Button1Click(Sender: TObject); 
var 
s : string; 
c : currency; 
begin 
SetRoundMode(rmNearest); 

c := 54321.245; 
s := ''; 
s := s + Format('Variable: %m',[c]); 
s := s + chr(13); 
s := s + Format(' Literal: %m',[54321.245]); 
ShowMessage(s); 
end; 

Leider mit rmNearest entscheidet Delphi die Zahl 54.321,245 näher 54.321,24 als 54321.25

+0

Das stimmt nicht genau. Wenn Sie den Wert von c: = 54321.244 ändern, wird es als $ 54.321,45 formatiert und es sollte $ 54.321,44 sein (ich wünschte, es wäre so einfach). Es scheint, dass die Verwendung eines erweiterten Typs anstelle von Währung die Arbeit dafür ist. –

+0

Meine Entschuldigung, @CapeCodGunny. Ich habe das obige bearbeitet – Hendra

+0

Entschuldigen Sie sich nicht, lernen wir alle. Offenbar wird der Währungstyp nicht wie der erweiterte Typ gerundet oder formatiert. Ich habe mir nur einige der Finanzfunktionen in Delphis 'Math-Einheit angeschaut und keiner von ihnen verwendet einen Währungstyp. Sie alle verwenden den erweiterten Typ. Also, wenn es für Delphi Math Unit funktioniert, funktioniert es für mich. :-) –

6

Es ist nicht möglich, RTL so zu runden, wie Sie möchten.Die Art und Weise, wie die Rundung in Delphi beeinflusst wird, ist die Verwendung von SetRoundMode, die sets the FPU conrol word für die Rundung, aber, soweit ich sagen kann, gibt es keine FPU-Unterstützung für die Rundung der genauen dazwischen zwischen oben (die in der Regel vermieden wird, weil es eine Vorspannung für erzeugt höhere Werte).

Sie müssen Ihre eigene Rundungsfunktion implementieren. Es gibt eine ausführliche Diskussion in Delphi Rounding thread auf Embarcadero Foren, die mehrere Lösungen enthält.

+0

Genau das habe ich gesucht. Vielen Dank. –