i'd use the Round( ) function if banker's rounding is ok. it returns an integer.
if you don't like banker's rounding you can use this:
// use this to not get "banker's rounding"
function HumanRound(X: Extended): integer;
// Rounds a number "normally": if the fractional
// part is >= 0.5 the number is rounded up (see RoundUp)
// Otherwise, if the fractional part is < 0.5, the
// number is rounded down
// RoundN(3.5) = 4 RoundN(-3.5) = -4
// RoundN(3.1) = 3 RoundN(-3.1) = -3
begin
// Trunc() does nothing except conv to integer. needed because return type of Int() is Extended
Result := Trunc(Int(X) + Int(Frac(X) * 2));
end;
my posting here is somewhat off-topic but still informative.
i looked into this at length since i needed to not be using banker's rounding. here are my findings. so far as i can see, this still doesn't get rid of banker's rounding
Value Meaning
rmNearest Rounds to the closest value. // default, bankers rounding
rmDown Rounds toward negative infinity.
rmUp Rounds toward positive infinity.
rmTruncate Truncates the value, rounding positive numbers down and negative numbers up.
rmNearest // default
0.500 0
1.500 2
2.450 2
2.500 2
2.550 3
3.450 3
3.500 4
3.550 4
rmDown
0.500 0
1.500 1
2.450 2
2.500 2
2.550 2
3.450 3
3.500 3
3.550 3
rmUp
0.500 1
1.500 2
2.450 3
2.500 3
2.550 3
3.450 4
3.500 4
3.550 4
rmTrunc
0.500 0
1.500 1
2.450 2
2.500 2
2.550 2
3.450 3
3.500 3
3.550 3
uses
math, sysutils, clipbrd;
var
s:string;
procedure trythis(sMode:string);
procedure tryone(d:double);
begin
s:=s+Format('%1.3f %d%s',[d,Round(d),#13+#10]);
end;
begin
s:=s+#13#10+sMode+#13#10;
tryone(0.50);
tryone(1.50);
tryone(2.45);
tryone(2.50);
tryone(2.55);
tryone(3.45);
tryone(3.50);
tryone(3.55);
end;
begin
s:=inttostr(integer(GetRoundMode));
SetRoundMode(rmNearest);
trythis('nearest');
SetRoundMode(rmDown);
trythis('down');
SetRoundMode(rmUp);
trythis('up');
SetRoundMode(rmTruncate);
trythis('trunc');
clipboard.astext:=s;
end.