Link to home
Start Free TrialLog in
Avatar of rvaldivia
rvaldivia

asked on

Problems using Delphi's round function - ROUND(39994.5)=39994, WHY?

Hi,
I'm using delphi's round option but I keep getting the following odd results

round(3.5) = 4
round(4.5) = 4

Can anybody help me to solve this?
Thanx in advance.
ASKER CERTIFIED SOLUTION
Avatar of wavget
wavget
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of _Katka_
Hi, try to use this function instead:

function NormalRound(X:Extended):Int64;
begin
  if Frac(X)>0.5 then Result:=Floor(X) else Result:=Ceil(X);
end;

regards,
Kate
Well rather use this one :)

function NormalRound(X:Extended):Int64;
begin
  if Frac(X)<0.5 then Result:=Floor(X) else Result:=Ceil(X);
end;

Kate
Avatar of BlackTigerX
BlackTigerX

or with
SetRoundMode(rmNearest)

as wavget suggested, then you can keep using the Round function
...or not... did the same thing after I used rmNearest and rmUp... use Katka's method...
I use this:

function Round5(X: Extended): Int64;
begin
  if abs(Frac(x)) <0.5
    then result:= Trunc(x)
    else begin
      if x < 0
        then result:= Trunc(x) -1
        else result:= Trunc(x) +1;
    end;
end;

regards
Pierre
The above function will round as follows:

decimals >= 0.5    -> round up
decimals < 0.5      -> round down
Katka,

I don't think Floor and Ceiling are built in Delphi functions (I think they're visual basic). Well, I can't find it anywere anyway...
Hi PierreC, they're in Math unit :)

Kate
Hi,

Use this simle function:

function RoundUp(X: Extended): Int64;
begin
  Result := Trunc(X) + Trunc(Frac(X) * 2);
end;

Regards, Geo
hi my 2 cents

http://www.delphibasics.co.uk/RTL.asp?Name=Round

12.4 rounds to  12
12.5 rounds to  12 // Round down to even
12.6 rounds to  13
   
13.4 rounds to  13
13.5 rounds to  14 // Round up to even
13.6 rounds to  14

if you can follow it - i think this could explain part of the problem (if its the same)
https://www.experts-exchange.com/questions/21091818/Rounding-numbers.html

after contacting borland it seems that this issue was resolved in the service pack for Delphi 7

DAvid
Kate, try your function with '-3.1', please. It doesn't work correctly for negative numbers.
wavget, I'm not able to find SetRoundMode function in my D5.

Regards, Geo
SimpleRoundTo from D7 uses asymmetric arithmetic rounding.

function SimpleRoundTo(const AValue: Double; const ADigit: TRoundToRange = -2): Double;

One thing when rounding floating point numbers. Sometimes a simple number 0.15 cannot be represented as 0.15 in floating point so its true representation is 0.149999999999999 This of course will round to 0.1 no mater which rounding function you use. Simple Test:

SimpleRoundTo(0.05, -1); = 0.1
SimpleRoundTo(0.15, -1); = 0.1 should = 0.2
SimpleRoundTo(0.25, -1); = 0.3
SimpleRoundTo(0.35, -1); = 0.3 should = 0.4
SimpleRoundTo(0.45, -1); = 0.5
SimpleRoundTo(0.55, -1); = 0.6

I work for an inventory company and this kind of floating point error is not acceptable. So we had to write our own that added .000001 before rounding to compensate for this.