Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Delphi 3 : Rounding

7 views
Skip to first unread message

Jim Schoen

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
How come when I round an even number plus one half, Delphi rounds down?
I can even do this in the IDE (Ctrl-F7). But It also occurs in my
programs.

In my program, ROUND (0.75*2009934) = ROUND (1507450.5)= 1,507,450.
With Turbo Pascal 6.0, this value rounded to 1,507,451.

ROUND(1.5) = 2
ROUND(2.5) = 2
ROUND(3.5) = 4
ROUND(4.5) = 4
ROUND (99.5) = 100
ROUND (100.5) = 100

The help on ROUND indicates that it should round to the number of
highest absolute value. (HELP is QUOTED BELOW).

Am I missing something?

The Round function rounds a real-type value to an integer-type value.
X is a real-type expression. Round returns a Longint value that is the
value of X rounded to the nearest whole number. If X is exactly halfway
between two whole numbers, the result is the number with the greatest
absolute magnitude.
If the rounded value of X is not within the Longint range, a run-time
error will be generated, which can be handled using the EInvalidOp
exception.


Rick Rogers (TeamB)

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
On Fri, 24 Jul 1998 15:25:55 -0500, Jim Schoen
<jschoen...@execpc.com> wrote:

> Am I missing something?

The help in D1-D3 is wrong. The help has been corrected in D4:

"X is a real-type expression. Round returns an Int64 value that is the


value of X rounded to the nearest whole number. If X is exactly

halfway between two whole numbers, the result is always the even
number."

This is called "Banker's rounding". Here's my standard text on the
topic. See the very end for a rounding function which works the way
you expect:

The Delphi documentation for the Round function is incorrect. The way
you've described Round working is the way it is supposed to work (and
has worked, since Borland Pascal 7).

That is how the Intel Numeric Processing Unit (NPU) rounds numbers by
default, and consequently that is how the Delphi Round() function
works. When the fractional part of the real is exactly 0.5 rounding
is done to the nearest =even= number.

Actually, it would be better to say that Intel chose this algorithm
because that's what IEEE floating point is supposed to do.

The following table shows why this method of rounding is necessary:

"error"
0.0 -> 0.0 0.0
0.1 -> 0.0 -0.1
0.2 -> 0.0 -0.2
0.3 -> 0.0 -0.3
0.4 -> 0.0 -0.4
0.5 -> ???
0.6 -> 1.0 0.4
0.7 -> 1.0 0.3
0.8 -> 1.0 0.2
0.9 -> 1.0 0.1

4 values are rounded down (0.1 .. 0.4) and 4 values are rounded up
(0.6 .. 0.9) and 0.0 isn't changed. If 0.5 is always rounded up, then
on average the errors would total 0.5, while if 0.5 is always rounded
down, then the average error would be -0.5.

By rounding 0.5 down half the time, and up the other half, the
average errors would balance out.

This illustrates how quickly rounding errors can accumulate in a
simple total.

IEEE "Traditional"
0.5 -> 0 1
1.5 -> 2 2
2.5 -> 2 3
3.5 -> 4 4
---------------------------------------------
Total 8 10
Error 0 2 ( 25%)

Accountants and bankers are aware of how traditional rounding can
distort their bookkeeping records over time. Hence, the IEEE
method is sometimes called "banker's rounding".

If you don't agree with the logic behind the way Delphi implements the

Round function, and you don't mind accumulating statistical errors,
then use this algorithm, which always rounds up:

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

--
Rick Rogers (TeamB) | Fenestra Technologies
http://www.fenestra.com/

Jim Schoen

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
Thanks Rick.

You answered me too quickly. Since I posted the reply, I did a search
on the Inprise bulletin boards and found your statement of 19-Jan-98.

I went here to remove my posted question, but you had already answered.
Thanks for the very quick reply. I understand the mathematical reason
for the "bankers rounding".

I was just trying to match to output created by Turbo 6.0 and was
researching why it was different with D3. Then I went to Delphi help
screens and wondered why my results were different than what help
implied.

Thanks. I should have searched the bulletin boards BEFORE I posted my
question.

Yorai Aminov (TeamB)

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
On Fri, 24 Jul 1998 15:25:55 -0500, Jim Schoen
<jschoen...@execpc.com> wrote:

>How come when I round an even number plus one half, Delphi rounds down?

It doesn't. It rounds x.5 to the nearest even number (Bankers round).

Yorai Aminov (TeamB)
http://ourworld.compuserve.com/homepages/yaminov

Rick Rogers (TeamB)

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
On Fri, 24 Jul 1998 16:00:53 -0500, Jim Schoen
<jschoen...@execpc.com> wrote:

> I went here to remove my posted question, but you had
> already answered.

Sorry, I'll try to answer a little slower next time :). It has been a
common question/complaint for years -- and TeamB did what it could to
ensure Inprise got the docs right in D4.

Roger Fang

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
Apparently Delphi uses statistical rounding (i.e.: 0-4 rounds down. 6-9
rounds up. 5 rounds down if previous digit is even, up if previous digit is
odd). I had also thought it used traditional rounding. This is good
however, since my program specifications requires statistical rounding. I
wonder if there is any way to specify/switch rounding methods? I can only
find one rounding function in the help.

Jim Schoen wrote in message <35B8ED...@execpc.com>...


>How come when I round an even number plus one half, Delphi rounds down?

Rick Rogers (TeamB)

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
On Fri, 24 Jul 1998 15:17:18 -0600, "Roger Fang"
<roger...@compuserve.com> wrote:

> I wonder if there is any way to specify/switch rounding methods?

There is, it involves flipping a bit in the Intel FPU. Or you could
use the other AlwaysRoundUp function which I posted in my other
message.

Dave Riley

unread,
Jul 26, 1998, 3:00:00 AM7/26/98
to
In article <35b901c3...@forums.borland.com>, ri...@fenestra.com (Rick
Rogers (TeamB))) wrote:

> There is, it involves flipping a bit in the Intel FPU. Or you could
> use the other AlwaysRoundUp function which I posted in my other
> message.

Please someone correct me if I'm wrong, but it would appear that the FPU
has no way of performing 'standard' rounding. It has 4 rounding modes,
none of which correspond to 'standard' rounding.

It seems strange that if you use:
Format ('%.0f, [ n ])
to convert a real 'n' to a text 'integer', then you do get standard
rounding (x.5 always rounded up to x+1).

Dave Riley
Tangent Software Ltd, Reading, UK

Rick Rogers (TeamB)

unread,
Jul 26, 1998, 3:00:00 AM7/26/98
to
On 26 Jul 1998 11:01:03 GMT, a...@cix.co.uk (Dave Riley) wrote:

> Please someone correct me if I'm wrong, but it would appear that the FPU
> has no way of performing 'standard' rounding

Actually, you know more about this than I do... I would use an OP
function to accomplish the goal, and wouldn't fool around with
switching the FPU.

> It seems strange

Agreed, you can see why this happens in SysUtils.pas.

0 new messages