问题
i have the following code to round the currency
function MyRound(value :currency) : integer;
begin
if value > 0 then
result := Trunc(value + 0.5)
else
result := Trunc(value - 0.5);
end;
it worked well so far, my problem now is if i want to round a currency like 999999989000.40 it is giving negative value since Truc takes int and MyRound also returns int.
My possible solutions is to convert currency to string and get the string before . and convert the string back to currency. Is this a right approach? i am new to delpi so pls help me out.
回答1:
You are overcomplicating matters. You can simply use Round
:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
C: Currency;
begin
C := 999999989000.4;
Writeln(Round(C));
C := 999999989000.5;
Writeln(Round(C));
C := 999999989000.6;
Writeln(Round(C));
C := 999999989001.4;
Writeln(Round(C));
C := 999999989001.5;
Writeln(Round(C));
C := 999999989001.6;
Writeln(Round(C));
Readln;
end.
which outputs
999999989000 999999989000 999999989001 999999989001 999999989002 999999989002
If you don't want banker's rounding, and you really do want your Trunc
logic then you do need to write your own function. But the problem with your function is that it was truncating to 32 bit integer. Make the function return a 64 bit integer:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Math;
var
C: Currency;
function MyRound(const Value: Currency): Int64;
begin
if Value > 0 then
result := Trunc(Value + 0.5)
else
result := Trunc(Value - 0.5);
end;
begin
C := 999999989000.4;
Writeln(MyRound(C));
C := 999999989000.5;
Writeln(MyRound(C));
C := 999999989000.6;
Writeln(MyRound(C));
C := 999999989001.4;
Writeln(MyRound(C));
C := 999999989001.5;
Writeln(MyRound(C));
C := 999999989001.6;
Writeln(MyRound(C));
Readln;
end.
999999989000 999999989001 999999989001 999999989001 999999989002 999999989002
回答2:
From my point of view, you have two options:
- You use the
Round
function, as David Heffernan pointed; - You can use the
SimpleRoundTo
function, as described here. The advantage ofSimpleRoundTo
is that it receives parameters ofSingle
,Double
andExtended
data types and they convert round very well numbers like those stated.
You don't need any type conversions. There are plenty of rounding functions already available to you. Just round the desired number.
回答3:
Take a look at John Herbster's rounding routines. They offer nearly any type of rounding you might want, e.g.:
drNone, {No rounding.}
drHalfEven,{Round to nearest or to even whole number. (a.k.a Bankers) }
drHalfPos, {Round to nearest or toward positive.}
drHalfNeg, {Round to nearest or toward negative.}
drHalfDown,{Round to nearest or toward zero.}
drHalfUp, {Round to nearest or away from zero.}
drRndNeg, {Round toward negative. (a.k.a. Floor) }
drRndPos, {Round toward positive. (a.k.a. Ceil ) }
drRndDown, {Round toward zero. (a.k.a. Trunc) }
drRndUp); {Round away from zero.}
I can't give you a link right now, but Google: decimal rounding John Herbster I think his latest rounding routines are in DecimalRounding_JH1.pas. His discussion of floating point rounding (somewhere on Embarcadero's website is a "must-read".
回答4:
This is what I actually use (would love to hear if there is any problems with this approach!):
function RoundingFunction(X: Real): Int64;
begin
Result := Trunc(SimpleRoundTo(X, 0));
end;
来源:https://stackoverflow.com/questions/15023973/rounding-a-currency