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?
+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.)
+0.24499 99999 99999 99555 91079 01499 37383 83054 73327 63671 875
(7) Welcome to the "real" world.
--
Doru
"John Herbster" <herb-sci1_AT_sbcglobal.net> wrote in message
news:40c8bfb6$1...@newsgroups.borland.com...
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
>
> 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
How do you know that you have _exactly_ 1.245 ?
--
Aage J.
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 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
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
---------------------------------------------------------------------------
Good question! For what good it does, I have set
followup to
borland.public.delphi.language.delphi.general
--JohnH