From: Trevor Toms |
|
Subject: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 3-Aug-2007 at 9:56:0 PST |
SimpleRoundTo is supposed to round midvalues up to the level of specified
precision, but some specific values fail this.
E.g. SimpleRoundTo(79.625, -2) gives the result 79.62 rather than the
expected 79.63.
We've got round it by a convoluted process of conversion from floats to
strings and back to floats again, but is there an alternative function
which works?
Trevor
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 10-Aug-2007 at 20:36:48 PST |
> > We've got round it by a convoluted process
> > of conversion from floats to strings and back
> > to floats again, but is there an alternative
> > function which works?
"David Marcus" wrote
> Changing the declaration of LFactor in the Delphi
> code to extended seems to help. I'd suggest
> changing all the doubles in the routine to
> extendeds. Of course, this won't help if the
> string doesn't have an exact binary representation
David, Most do not!
> and the binary representation is on the other side
> of the 5 threshold than the string, but I wonder
> if it will make the routine work properly when the
> string does have such a representation.
You can save yourself a lot of wondering by properly
using the rounding functions in DecimalRounding_JH1.
Rgds, JohnH
--
Support the movement to add floating and fixed
decimal fraction numbers to Delphi.
http://qc.borland.com/wc/qcmain.aspx?d=28022
DecimalRounding (JH1)
http://cc.codegear.com/Item.aspx?id=21909
IEEE Number Analyzer (project code)
http://cc.codegear.com/item.aspx?id=23631
ExactFloatToStr
http://cc.codegear.com/Item.aspx?id=19421
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 11-Aug-2007 at 20:54:9 PST |
> > > Changing the declaration of LFactor in the
> > > Delphi code to extended seems to help.
"David Marcus" wrote
> I'm sure the routines are useful, but my point
> was that the Delphi routine seems to have a bug.
There is no doubt about that.
> There are two separate issues:
David,
> conversion from decimal strings to binary floating
> point
What do you see as the problem above? Maybe the
fact that most decimal fractions have no exact
representation in floating binary point
variables or something else?
> and rounding of binary floating point numbers [to
> fixed decimal fraction]
> IEEE arithmetic works pretty well, in general. But,
> trying to round a floating point number by using
> doubles is not a good idea.
Then why do we do so often? Is it perhaps because
there is not a good alternative?
> If you really want to round a decimal string, then
> converting it to a binary floating point number
> is not a good idea.
> But, if you want to round a binary floating point
> number, then a simple fix will make the Delphi
> routine do it much more reliably.
A proof would be welcome. Please include a statement
of the rounding rule along with the code and test
results.
Regards, JohnH
--
Support the movement to add floating and fixed
decimal fraction numbers to Delphi.
http://qc.borland.com/wc/qcmain.aspx?d=28022
DecimalRounding (JH1)
http://cc.codegear.com/Item.aspx?id=21909
IEEE Number Analyzer (project code)
http://cc.codegear.com/item.aspx?id=23631
ExactFloatToStr
http://cc.codegear.com/Item.aspx?id=19421
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 12-Aug-2007 at 17:13:30 PST |
"David Marcus" wrote
> function F (
> const AValue: extended;
> const ADigit: TRoundToRange = -2): extended;
> var LFactor: extended;
> begin
> LFactor := IntPower(10, ADigit);
> if AValue < 0 then
> Result := Trunc((AValue / LFactor) - 0.5) * LFactor
> else
> Result := Trunc((AValue / LFactor) + 0.5) * LFactor;
> end;
> 1. SimpleRoundTo's use of "double" instead of
> "extended" is a bug.
David, Yes, it should have been an extended type.
I would call this a case of thoughtlessness.
Looking again at the D7 Help for SimpleRoundTo, it
claims that it "Rounds a floating-point value to a
specified digit or power of ten using asymmetric
arithmetic rounding." From my Googling, I believe
that asymmetric arithmetic rounding normal means
that rounding should be to the nearest and points
midway between are suppose to round toward plus inf.
> 2. The rounding routines that writeln uses are
> superior.
Superior -- in what regard? I have never seen a
statement of what rounding rule that they are
supposed to follow.
> Two other facts that are relevant:
> 3. Rounding by rescaling (as SimpleRoundTo or my
> fixed version does) makes you susceptible to loss
> of precision.
All rounding makes you susceptible to loss of
precision.
> 4. Conversion of decimal strings to binary floating
> point is rarely exact.
I note that in your test you are using WriteLn() to
give you strings with numbers like
1.35000000000000E-0001
Are you aware that these are not exact? The exact
number would be something like
0.13499 99999 99999 99999 13263 82620 11596
45279 40377 59304 04663 08593 75
If you really want to know the exact value, you should
be using something like my ExactFloatToStr() routines
that are available from CodeCentral.
You might want to check some of the small differences
between you F function and my DecimalRoundDbl function
(available from CodeCentral as part of the
DecimalRounding_JH1 module.)
When rounding the nominally "0.045" value
Inp=+ 0.04499 99999 99999 99999 82381 71469 71105
52947 37889 19858 63447 18933 10546 875
Your code gives
DsF=+ 0.04999 99999 99999 99999 72894 94568
78623 89149 81367 99782 51457 21435 54687 5
And DecimalRoundDbl gives
DRD=+ 0.05000 00000 00000 00000 06776 26357
80344 02712 54658 00054 37135 69641 11328 125
Yours is close, but not as close as it could be, given
that it is returning an extended result.
Regards, JohnH
--
Support the movement to add floating and fixed
decimal fraction numbers to Delphi.
http://qc.borland.com/wc/qcmain.aspx?d=28022
DecimalRounding (JH1)
http://cc.codegear.com/Item.aspx?id=21909
IEEE Number Analyzer (project code)
http://cc.codegear.com/item.aspx?id=23631
ExactFloatToStr
http://cc.codegear.com/Item.aspx?id=19421
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 3-Aug-2007 at 15:17:45 PST |
"James Miller" wrote
> I am pretty sure that Delphi's Currency type
> calculations also use bankers rounding. Is there
> a compiler switch or something to make it use
> simple rounding?
A good programmer should know that there is no such
thing as "simple rounding" -- by that, I mean a
rounding rule that most programmers can agree on.
At least "bankers rounding" is a rule that most
programmers can agree on.
That aside, when ordinary programmers get caught in
the trap of using floating *binary* point numbers,
to represent (fixed or floating) decimal fraction
numbers and have to do any kind of rounding, then
they stumble all over themselves.
The problem, of course, is that general decimal
fractions cannot be exactly represented as
floating binary point numbers. This leads to
problems deciding what the floating binary point
number is really supposed to represent in decimal
fraction terms. My DecimalRounding package that
Willem mentioned solves this problem.
However, as someone ready to step into retirement
who has for many years tried both to educate the
ignorant and to push for incorporating actual
fixed and floating decimal fraction into Delphi,
I am really disappointed that I am still reading
such ill informed discussion of this problem.
Rgds, JohnH
--
Support the movement to add floating and fixed
decimal fraction numbers to Delphi.
http://qc.borland.com/wc/qcmain.aspx?d=28022
DecimalRounding (JH1) -- allows you to do about
nine kinds of decimal rounding with floating
binary point numbers.
http://cc.codegear.com/Item.aspx?id=21909
IEEE Number Analyzer (project source code) -- a
program that will convert a decimal fraction
number into the nearest possible floating binary
point number (i.e. single, double, or extended)
http://cc.codegear.com/item.aspx?id=23631
ExactFloatToStr -- a function for converting a
floating binary point number to its exact
decimal fraction values in a ASCII string.
http://cc.codegear.com/Item.aspx?id=19421
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 4-Aug-2007 at 1:19:13 PST |
"Ralf Jansen" wrote
> ... For floating point types SimpleRoundTo() does
> arithmetic rounding.
Ralf,
At least for D7, SimpleRoundTo was screwed up. See
open QualityCentral reports #8070 and #8143:
_RoundTo and SimpleRoundTo are very sick_
http://qc.codegear.com/wc/qcmain.aspx?d=8070
_Replace RoundTo and SimpleRoundTo_
http://qc.codegear.com/wc/qcmain.aspx?d=8143
I would not recommend RoundTo or SimpleRoundTo to
anyone.
What is "arithmetic rounding"?
The types that I am familiar with include:
(Abbr: 'HalfEven'; Dscr: 'to nearest or even (bankers)'),
(Abbr: 'HalfPos' ; Dscr: 'to nearest or toward positive'),
(Abbr: 'HalfNeg' ; Dscr: 'to nearest or toward negative'),
(Abbr: 'HalfDown'; Dscr: 'to nearest or toward zero'),
(Abbr: 'HalfUp' ; Dscr: 'to nearest or away from zero'),
(Abbr: 'RndNeg' ; Dscr: 'toward negative (floor)'),
(Abbr: 'RndPos' ; Dscr: 'toward positive (ceil )'),
(Abbr: 'RndDown' ; Dscr: 'toward zero (trunc)'),
(Abbr: 'RndUp' ; Dscr: 'away from zero') );
The above are from my module DecimalRounding_JH1.
And then there is "statistical rounding" which is not
included in the current DecimalRounding_JH1.
> By default, the RoundTo() method does bankers rounding
> but that can be changed via the SetRoundMode() function.
I would not say that RoundTo() *does* bankers rounding.
The D7 help says that RoundTo() *uses* bankers rounding,
which is technically true; but the results are not what
the innocent programmer would expect to see. Instead,
it gives this:
RoundTo(1.235,-2) ==> 1.24
RoundTo(1.245,-2) ==> 1.25
If you examine more closely the real numbers being passed
into and out of the RoundTo function, you will observe for
RoundingMode: rmNearest
RoundTo(1.235,-2) ==> 1.24
Exact Inp: + 1.23500 00000 00000 09769 96261 67013
77555 72795 86791 99218 75
Exact Out: + 1.23999 99999 99999 99111 82158 02998
74767 66109 46655 27343 75
RoundTo(1.245,-2) ==> 1.25
Exact Inp: + 1.24500 00000 00000 10658 14103 64015
02788 06686 40136 71875
Exact Out: + 1.25
Here is the code that I used for the test:
Uses Math, ExactFloatToStr_JH0;
procedure TForm1.Button1Click(Sender: TObject);
{sub}procedure TestRT(const AValue: Double; const ADigit:
TRoundToRange);
var AVStr, RVStr: string; RVal: double;
begin
RVal := RoundTo(AValue,ADigit);
Memo1.Lines.Add(Format(' RoundTo(%S,%D) ==> %S',
[FloatToStr(AValue),ADigit,FloatToStr(RVal)]));
AVStr := ExactFloatToStrEx(AValue);
Memo1.Lines.Add(Format(' ExactInp: %S',[AVStr]));
RVStr := ExactFloatToStrEx(RVal);
Memo1.Lines.Add(Format(' ExactOut: %S',[RVStr]))
end;
var ORM, RM: TFPURoundingMode;
const RoundingModeStrs: array [TFPURoundingMode] of string =
('rmNearest','rmDown','rmUp','rmTruncate');
begin
For RM := rmNearest to rmTruncate do begin
ORM := SetRoundMode(RM);
Memo1.Lines.Add('RoundingMode: '+RoundingModeStrs[RM]);
Try
TestRT(1.235, -2); // 1.24
TestRT(1.245, -2); // 1.24
Finally
SetRoundMode(ORM);
End;
end;
end;
I will post the source for the whole test if anyone is interested.
Rgds, JohnH
--
Support the movement to add floating and fixed
decimal fraction numbers to Delphi.
http://qc.borland.com/wc/qcmain.aspx?d=28022
DecimalRounding (JH1)
http://cc.codegear.com/Item.aspx?id=21909
IEEE Number Analyzer (project code)
http://cc.codegear.com/item.aspx?id=23631
ExactFloatToStr
http://cc.codegear.com/Item.aspx?id=19421
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 5-Aug-2007 at 14:31:35 PST |
"Q Correll" wrote
> | I will post the source for the whole test if anyone is
interested.
> I am interested.
I just posted it in b.p.attachments group under subject:
T_RoundTo_3 -- Test for bug in RoundTo functions
--JohnH
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 12-Aug-2007 at 14:29:26 PST |
"David Marcus" wrote
> ...
> The best way to round numbers for output is to
> use write or writeln.
Do you mean that you would use Write() or WriteLn()
to round a number stored in a floating binary point
variable to a string format? If so how do you spec
what kind of rounding to do?
> If you need to round a number to store it into a
> variable, then Delphi doesn't make this easy.
In my opinion, Delphi makes it too easy. Programmers
are frequently using StrToFloat() and assignments like
:= ; or
:= /; or
:=
without understand what rounding or loss of precision
or data is happening.
> > > But, if you want to round a binary floating point
> > > number, then a simple fix will make the Delphi
> > > routine do it much more reliably.
> > A proof would be welcome. Please include a statement
> > of the rounding rule along with the code and test
> > results.
> program Test;
> ...
David,
Thanks I will check out your proof and respond later.
Regards, JohnH
|
From: Serge Dosyukov \(Dragon Soft\) |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 3-Aug-2007 at 10:6:43 PST |
Accordinly to this (snippet from help file)
SimpleRoundTo(1234567, 3) 1234000
SimpleRoundTo(1.234, -2) 1.23
SimpleRoundTo(1.235, -2) 1.24
SimpleRoundTo(-1.235, -2) -1.23
it is a bug
PS. I am not sure about last row thought ;)
I would think that Wiki shows it right -
http://en.wikipedia.org/wiki/Rounding - one just have to decide which method
to use
> SimpleRoundTo is supposed to round midvalues up to the level of specified
> precision, but some specific values fail this.
>
> E.g. SimpleRoundTo(79.625, -2) gives the result 79.62 rather than the
> expected 79.63.
|
From: David Marcus |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 14-Aug-2007 at 18:25:29 PST |
"John Herbster" wrote:
> However the problem that most programmers run into
> is still not fixed. Consider what will happen if the
> input value is from a double precision variable, such
> as might be retreived from a data table, instead of
> an extended variable. Then you if you are rounding
> "100000.015", what you will get is this:
> Inp=+ 1 00000.01499 99999 99417 92339 08653 25927
> 73437 5
> DF2=+ 1 00000.00999 99999 99998 01048 03398 71719
> 47956 08520 50781 25
> DRD=+ 1 00000.02000 00000 00003 12638 80373 44440
> 81783 29467 77343 75
> and you can see that again DRD is closer to the right
> result. If you step through the DF2 calculation you
> can see why. That is why my decimal rounding routines
> use carefully chosen fudge factors.
Sure. If you assign to a double, you will lose precision. Binary
floating point is not decimal floating point. People who think it is,
will be surprised.
Whether 100000.02 is the "right" result depends on how you define the
problem. 100000.015 rounded to two digits is 100000.02, but Inp rounded
to two digits is 100000.01.
--
David Marcus
|
From: David Marcus |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 14-Aug-2007 at 18:9:9 PST |
"John Herbster" wrote:
> "David Marcus" wrote
> > X := 0.49999999999999999;
> > writeln( X );
>
> David, I am glad that you are interested in this
> important stuff.
>
> However, you need to give up on that WriteLn(X).
> It is lying to you.
Never said it was giving the exact value. Was just showing an example of
how writeln performs.
> If your variable X above is of type extended, then
> after the assignment, it will contain exactly
> +0.49999 99999 99999 98999 82349 58821 22159
> 62812 47911 97478 77120 97167 96875
> not 5.00000000000000E-0001
Which is the correctly rounded value, so writeln seems to be doing fine,
although one might ask why writeln doesn't give more digits by default.
--
David Marcus
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 13-Aug-2007 at 17:5:58 PST |
"David Marcus" wrote
> X := 0.49999999999999999;
> writeln( X );
David, I am glad that you are interested in this
important stuff.
However, you need to give up on that WriteLn(X).
It is lying to you.
If your variable X above is of type extended, then
after the assignment, it will contain exactly
+0.49999 99999 99999 98999 82349 58821 22159
62812 47911 97478 77120 97167 96875
not 5.00000000000000E-0001
You can get the exact values with functions
in my ExactFloatToStr module which is available
from CodeCentral or you can write your own.
Regards, JohnH
--
Support the movement to add floating and fixed
decimal fraction numbers to Delphi.
http://qc.borland.com/wc/qcmain.aspx?d=28022
DecimalRounding (JH1)
http://cc.codegear.com/Item.aspx?id=21909
IEEE Number Analyzer (project code)
http://cc.codegear.com/item.aspx?id=23631
ExactFloatToStr
http://cc.codegear.com/Item.aspx?id=19421
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 13-Aug-2007 at 17:6:40 PST |
David wrote
> function DsF (
> const AValue: extended;
> const ADigit: TRoundToRange = -2): extended;
> var LFactor: extended;
> begin
> LFactor := IntPower(10, ADigit);
> if AValue < 0 then
> Result := Trunc((AValue / LFactor) - 0.5) * LFactor
> else
> Result := Trunc((AValue / LFactor) + 0.5) * LFactor;
> end;
David, Please note that if you change your fucntion to
function DF2
(const AValue: extended;
const ADigit: TRoundToRange = -2)
: extended;
var LFactor: extended;
begin
LFactor := IntPower(10, -ADigit);
if AValue < 0
then Result := Trunc((AValue*LFactor) - 0.5)/LFactor
else Result := Trunc((AValue*LFactor) + 0.5)/LFactor;
end;
then the accuracy will be improved in a lot of cases.
Here are the results for an input of "0.045":
Inp=+ 0.04500 00000 00000 00000 16263 03258 72825
66510 11179 20130 49125 67138 67187 5
DsF=+ 0.04999 99999 99999 99999 72894 94568 78623
89149 81367 99782 51457 21435 54687 5
DF2=+ 0.05000 00000 00000 00000 06776 26357 80344
02712 54658 00054 37135 69641 11328 125
DRD=+ 0.05000 00000 00000 00000 06776 26357 80344
02712 54658 00054 37135 69641 11328 125
where DRD is from my DecimalRoundDouble function.
However the problem that most programmers run into
is still not fixed. Consider what will happen if the
input value is from a double precision variable, such
as might be retreived from a data table, instead of
an extended variable. Then you if you are rounding
"100000.015", what you will get is this:
Inp=+ 1 00000.01499 99999 99417 92339 08653 25927
73437 5
DF2=+ 1 00000.00999 99999 99998 01048 03398 71719
47956 08520 50781 25
DRD=+ 1 00000.02000 00000 00003 12638 80373 44440
81783 29467 77343 75
and you can see that again DRD is closer to the right
result. If you step through the DF2 calculation you
can see why. That is why my decimal rounding routines
use carefully chosen fudge factors.
Regards, JohnH
--
Support the movement to add floating and fixed
decimal fraction numbers to Delphi.
http://qc.borland.com/wc/qcmain.aspx?d=28022
DecimalRounding (JH1)
http://cc.codegear.com/Item.aspx?id=21909
IEEE Number Analyzer (project code)
http://cc.codegear.com/item.aspx?id=23631
ExactFloatToStr
http://cc.codegear.com/Item.aspx?id=19421
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 14-Aug-2007 at 19:39:33 PST |
> > "100000.015", what you will get is this:
> > Inp=+ 1 00000.01499 99999 99417 92339 08653 25927
> > 73437 5
"David Marcus" wrote
> Whether 100000.02 is the "right" result depends
> on how you define the problem. 100000.015 rounded
> to two digits is 100000.02, but Inp rounded > to
> two digits is 100000.01.
Dear David,
The goal in writing my DecimalRounding package was to
help programmers having to use floating binary point
numbers for applications requiring decimal fraction
output. Copied here (from the beginning of that package)
is the problem as I see it and how that package solved
it.
"ROUTINES FOR ROUNDING IEEE-754 FLOATS TO SPECIFIED
NUMBER OF DECIMAL FRACTION DIGITS"
"Because, in general, numbers with decimal fractions
cannot be exactly represented in IEEE-754 floating
binary point variables, error limits are used to
determine if the input numbers are intended to
represent an exact decimal fraction rather than a
nearby value. Thus an error limit will be taken
into account when deciding that a number input such
as 1.295, which internally is represented as
1.29499 99999 …, really should be considered exactly
1.295 and that 0.29999 99999 ... really should be
interpreted as 0.3 when applying the rounding rules."
"These routines round input values to fit as closely
as possible to an output number with desired number
of decimal fraction digits. "
Good luck, JohnH
|
From: David Marcus |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 14-Aug-2007 at 20:17:57 PST |
"John Herbster" wrote:
> The goal in writing my DecimalRounding package was to
> help programmers having to use floating binary point
> numbers for applications requiring decimal fraction
> output. Copied here (from the beginning of that package)
> is the problem as I see it and how that package solved
> it.
>
> "ROUTINES FOR ROUNDING IEEE-754 FLOATS TO SPECIFIED
> NUMBER OF DECIMAL FRACTION DIGITS"
>
> "Because, in general, numbers with decimal fractions
> cannot be exactly represented in IEEE-754 floating
> binary point variables, error limits are used to
> determine if the input numbers are intended to
> represent an exact decimal fraction rather than a
> nearby value. Thus an error limit will be taken
> into account when deciding that a number input such
> as 1.295, which internally is represented as
> 1.29499 99999 …, really should be considered exactly
> 1.295 and that 0.29999 99999 ... really should be
> interpreted as 0.3 when applying the rounding rules."
>
> "These routines round input values to fit as closely
> as possible to an output number with desired number
> of decimal fraction digits. "
That's fine. But, not all people wanting to round a floating point
number have this goal. And, many people who get tangled up with this
problem are simply misusing floating point.
--
David Marcus
|
From: Anders Isaksson |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 6-Aug-2007 at 3:2:42 PST |
Wayne Niddery [TeamB] wrote:
> No, it is fully documented "Bankers" rounding. Rounding is to the
> nearest even value.
But that's not what the D2006 Help says about SimpleRoundTo:
"SimpleRoundTo uses asymmetric arithmetic 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 always rounds to
the larger value."
But then the examples in the Help are meaningless and don't support
neither the above claim nor Banker's Rounding.
Looking at the source, it definitely is trying to do something else
than Banker's Rounding. It also seems the part "This method always
rounds to the larger value." actually should read "This method always
rounds to the larger *absolute* value."
All that aside from the fact that it doesn't work...
--
Anders Isaksson, Sweden
BlockCAD: http://web.telia.com/~u16122508/proglego.htm
Gallery: http://web.telia.com/~u16122508/gallery/index.htm
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 6-Aug-2007 at 8:30:54 PST |
> > No, it is fully documented "Bankers" rounding.
> > Rounding is to the nearest even value.
"Anders Isaksson" wrote
> But that's not what the D2006 Help says about
> SimpleRoundTo:
> "SimpleRoundTo uses asymmetric arithmetic 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 always
> rounds to the larger value."
"To the larger value" to me would imply that
-1.5 would go to -2, and +1.5 would go to +2.
To me, that would be symmetric, not asymmetric.
But I have some doubt. Am I wrong? The Help
writers could have made written this more clearly.
Given, our present IQs there is no such thing as
"simple rounding".
Regards, JohnH
|
From: Andrew Fiddian-Green |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 3-Aug-2007 at 10:17:13 PST |
Not 100% sure about this, but I think that -- in the case of numbers that
lie *exactly* half way between two choices -- the function uses "bankers
rounding" so as to eliminate the statistical bias you would otherwise get if
"half way" numbers were always (say) rounded down...
i.e. 79.625 would round to 79.62 but 79.635 would round to 79.64
Regards,
AndrewFG
|
From: John Herbster |
|
Subject: Re: Bug in Delphi SimpleRoundTo function? |
NewsGroup: borland.public.delphi.non-technical |
Date Posted: 4-Aug-2007 at 2:0:14 PST |
"Ralf Jansen" wrote
> But Trevor is using SimpleRoundTo and SimpleRoundTo is meant to do
Arithmetic
> rounding. So 79.62 is wrong.
Ralf,
According to
http://www.diycalculator.com/popup-m-round.shtml
"arithmetic rounding" is half-up toward positive for positive
numbers.
So how do you explain this fact:
SimpleRoundTo(79.615,-2) ==> 79.61
ExactInp: + 79.61499 99999 99994 88409 23025 27278 66172 79052
73437 5
ExactOut: + 79.60999 99999 99999 43156 58113 91919 85130 31005
85937 5
Rgds, JohnH
|