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

Strange behaviour on RoundTo

18 views
Skip to first unread message

Doru R

unread,
Jun 10, 2004, 2:22:49 PM6/10/04
to
I use a function that doesn't work properly.

var
cTest : currency;
.............
cTest := RoundTo(0.245,-2);

cTest -> 0.24 It was supposed to return 0.25.
0.245 is a result of a calculation a*b/100; a,b are currency
If I use the same function in a new project it works.

What is wrong here?

John Herbster

unread,
Jun 10, 2004, 4:10:49 PM6/10/04
to

"Doru R" <doru...@rogers.com> wrote

> var cTest : currency;
> .............
> cTest := RoundTo(0.245,-2);
> cTest -> 0.24 It was supposed to return 0.25.
> 0.245 is a result of a calculation a*b/100; a,b are currency
> If I use the same function in a new project it works.

+0.24499 99999 99999 99555 91079 01499 37383 83054 73327 63671 875

Oh dear! Where do I start? Here are a few facts:

(1) Here is the header for Math.RoundTo
function RoundTo(const AValue: Double; const ADigit: TRoundToRange):
Double;
Note that the input and output parameters are type double.

(2) As you may be aware, floating binary number types, in
general, cannot exactly represent decimal fraction numbers
like your "0.245". The nearest that it can get in a double is
+0.24499 99999 99999 99555 91079 01499 37383
83054 73327 63671 875
(You can download my exact-float-to-string routines from
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=19421)

(3) So if you were to round this to the nearest two decimal
number, you would get "0.24". Thus the input number is rarely
on the half-way point where the "bankers rounding" aspect
of RoundTo to have an effect.

(4) I am curious as to why you figure that you should get "0.25".
From reading the Help description and without any knowledge
from my ExactFloatToStr, I could not guess which way the
rounding would go.

(5) You should see QualityCentral reports #8070 and #8143
for more information on the performance of RoundTo and
SimpleRoundTo.

(6) If you really want to round numbers of type currency
then you should write you own currency rounding -- like
function RoundCurrencyToCents(cur: currency): currency;
var i, j: Int64; k: integer;
begin
i := round(cur*10000);
j := i div 100; k := i mod 100;
if abs(k) >= 50
then j := j + Sign(k);
Result := j/100;
end; {Very un-tested}
This is very untested, because I have incomplete knowledge
of your rounding rules.

(6) Welcome to the "real" world.

--
Regards, John Herbster
(Support the movement to add floating and fixed
decimal fraction numbers to the language.)

John Herbster

unread,
Jun 10, 2004, 4:12:26 PM6/10/04
to

"Doru R" <doru...@rogers.com> wrote

> var cTest : currency;
> .............
> cTest := RoundTo(0.245,-2);
> cTest -> 0.24 It was supposed to return 0.25.
> 0.245 is a result of a calculation a*b/100; a,b are currency
> If I use the same function in a new project it works.

+0.24499 99999 99999 99555 91079 01499 37383 83054 73327 63671 875

(7) Welcome to the "real" world.

Doru R

unread,
Jun 11, 2004, 8:26:25 AM6/11/04
to

Thanks John for the reply.
4) I took an example from the help which says:
RoundTo(1.235, -2) Result: 1.24

--

Doru

"John Herbster" <herb-sci1_AT_sbcglobal.net> wrote in message
news:40c8bfb6$1...@newsgroups.borland.com...

John Herbster

unread,
Jun 11, 2004, 10:35:40 AM6/11/04
to

"Doru R" <doru...@rogers.com> wrote

> Thanks John for the reply.
> 4) I took an example from the help which says:
> RoundTo(1.235, -2) Result: 1.24

Doru, I see. As you can tell from the Quality Central reports
#8070 and #8143 and the comments therein, Math.RoundTo
and Math.SimpleRoundTo are in bad shape.
http://qc.borland.com/wc/wc.exe/details?ReportID=8143
http://qc.borland.com/wc/wc.exe/details?ReportID=8070
I recommend that you make your own routines or use the
decimal routines that I have up loaded to CodeCentral.
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=17998

--
Regards, JohnH
Quality Central, bug status & reporting http://qc.borland.com/
Code Central http://codecentral.borland.com/codecentral/ccweb.exe

Benny Joseph

unread,
Jun 12, 2004, 2:07:07 AM6/12/04
to
Doru R wrote:

>
> Thanks John for the reply.
> 4) I took an example from the help which says:
> RoundTo(1.235, -2) Result: 1.24
>

Hi

That was not fair. It seems you skipped the line just below the line
you took in the same help.

----------- CUT AND PASTE FROM HELP -------------------------
RoundTo uses "Banker's Rounding" to determine how to round values that
are exactly midway between the two values that have the desired number
of significant digits. This method rounds to an even number in the case
that AValue is not nearer to either value.

The following examples illustrate the use of RoundTo:

Expression Value

RoundTo(1234567, 3) 1234000
RoundTo(1.234, -2) 1.23
RoundTo(1.235, -2) 1.24
RoundTo(1.245, -2) 1.24

Note: The behavior of RoundTo can be affected by the Set8087CW
procedure or SetRoundMode function.
-------------------------------------------------------------

It clearly state RoundTo(1.245, -2) will be 1.24

--
Benny Joseph
Inspired Technologies

Using Xana News 1.16.1.13

Aage Johansen

unread,
Jun 12, 2004, 10:25:31 AM6/12/04
to
Benny Joseph wrote:
> ...

> It clearly state RoundTo(1.245, -2) will be 1.24


How do you know that you have _exactly_ 1.245 ?


--
Aage J.

John Herbster

unread,
Jun 12, 2004, 12:03:01 PM6/12/04
to

> How do you know that you have _exactly_ 1.245 ?

FYI (for your information):

StrToFloat(1.245) will give as an extended and a double
+1.24500 00000 00000 00000 43368 08689 94201
77360 29811 20347 97668 45703 125
+1.24500 00000 00000 10658 14103 64015 02788
06686 40136 71875

StrToFloat(0.245) will give as an extended and a double
+0.24500 00000 00000 00000 43368 08689 94201
77360 29811 20347 97668 45703 125


+0.24499 99999 99999 99555 91079 01499 37383
83054 73327 63671 875

To convert your own floats to exact strings, download
ExactFloatToStr_JH0 -- Exact Float to String Routines
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=19421

--
Regards, JohnH
Code Central http://codecentral.borland.com/codecentral/ccweb.exe

Benny Joseph

unread,
Jun 12, 2004, 1:40:27 PM6/12/04
to
Aage Johansen wrote:

> Benny Joseph wrote:
> > ...
> > It clearly state RoundTo(1.245, -2) will be 1.24
>
>

> How do you know that you have exactly 1.245 ?

Hi,

No, I don't. And If you believe JohnH, 1.245 is something else!! And he
is right too.

And I was just responding to Doru's statement

>>I took an example from the help which says:
>> RoundTo(1.235, -2) Result: 1.24

to JohnH's question

>>I am curious as to why you figure that you should get "0.25".


Regards

Kjell Rilbe

unread,
Jun 13, 2004, 4:24:10 PM6/13/04
to
This is an interesting thread, but what is it doing in this discussion
group?

Kjell

John Herbster wrote:

>>How do you know that you have _exactly_ 1.245 ?
>
>
> FYI (for your information):
>
> StrToFloat(1.245) will give as an extended and a double
> +1.24500 00000 00000 00000 43368 08689 94201
> 77360 29811 20347 97668 45703 125
> +1.24500 00000 00000 10658 14103 64015 02788
> 06686 40136 71875
>
> StrToFloat(0.245) will give as an extended and a double
> +0.24500 00000 00000 00000 43368 08689 94201
> 77360 29811 20347 97668 45703 125
> +0.24499 99999 99999 99555 91079 01499 37383
> 83054 73327 63671 875
>
> To convert your own floats to exact strings, download
> ExactFloatToStr_JH0 -- Exact Float to String Routines
> http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=19421
>


--
---------------------------------------------------------------------------
Kjell Rilbe
Home: +46 8 7610734
Cell: +46 733 442464
---------------------------------------------------------------------------
"If there's a price for bein' me, that's one I'll have to pay"
Aaron Tippin
---------------------------------------------------------------------------

John Herbster

unread,
Jun 13, 2004, 4:58:29 PM6/13/04
to

"Kjell Rilbe" <kril...@mblock.home.se> wrote

> This is an interesting thread, but what is it doing in
> this discussion group?

Good question! For what good it does, I have set
followup to
borland.public.delphi.language.delphi.general
--JohnH

0 new messages