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

Does Str() round up for you?

11 views
Skip to first unread message

Chrismo

unread,
Sep 15, 1999, 3:00:00 AM9/15/99
to
(Another annoying rounding thread ...)

I'm using Orpheus controls in my app. When the user enters 40.085, for
example, the control displays 40.09. I checked their source, they are
calling Str to format the double for display.

I asked, why do that since Str rounds up, and the rest of Delphi depends on
the processor and does banker's? All my replies have been, "When I try what
you are doing, I see banker's rounding."

So I wrote the following - can anyone tell me what they get when they use it
both with BankerRound true and false? BankerRound = false always rounds up
for me, using the Str() call. TurboPower seems to be claiming it always does
Banker's Round. If they are correct - then the following function should
always banker's round, regardless of the BankerRound param:

function RoundCurrency(Value: currency; DecimalPlaces: integer;
BankerRound: boolean): currency;
var
Factor : Extended;
Width: integer;
SResult: string;
begin
if DecimalPlaces > 3 then
DecimalPlaces := 3
else if DecimalPlaces < 0 then
DecimalPlaces := 0;

Factor := Power(10, DecimalPlaces);
if BankerRound then
Result := Round(Value * Factor) / Factor
else begin
Width := Length(FloatToStr(Trunc(Value)));
Str((Value * Factor):Width:0, SResult);
Result := StrToCurr(SResult) / Factor;
end;
end;


Rick Rogers (TeamB)

unread,
Sep 15, 1999, 3:00:00 AM9/15/99
to
> I asked, why do that since Str rounds up, and the rest of Delphi
> depends on the processor and does banker's?

This statement is slightly inaccurate, and is probably the source of your
frustrations. How the CPU performs rounding can be changed by setting a
control bit, and I've heard that several MS DLLs set this bit.

> can anyone tell me what they get when they use it both with
> BankerRound true and false?

uses
Math;

function RoundCurrency(Value: currency; DecimalPlaces: integer;
BankerRound: boolean): currency;
var
Factor : Extended;
Width: integer;
SResult: string;
begin
if DecimalPlaces > 3 then
DecimalPlaces := 3
else if DecimalPlaces < 0 then
DecimalPlaces := 0;

Factor := Power(10, DecimalPlaces);
if BankerRound then
Result := Round(Value * Factor) / Factor
else begin
Width := Length(FloatToStr(Trunc(Value)));
Str((Value * Factor):Width:0, SResult);
Result := StrToCurr(SResult) / Factor;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(FloatToStr(RoundCurrency(40.085, 2, True))); // 4.08
ShowMessage(FloatToStr(RoundCurrency(40.085, 2, False))); // 4.09
end;


Chrismo

unread,
Sep 15, 1999, 3:00:00 AM9/15/99
to
> This statement is slightly inaccurate, and is probably the source of your
> frustrations. How the CPU performs rounding can be changed by setting a
> control bit, and I've heard that several MS DLLs set this bit.

Ah ... thanks for this tidbit. I thought I'd read in the Intel instruction
set that this was configurable. I hadn't heard about the .dll part.

> > can anyone tell me what they get when they use it both with
> > BankerRound true and false?

> procedure TForm1.Button1Click(Sender: TObject);
> begin
> ShowMessage(FloatToStr(RoundCurrency(40.085, 2, True))); // 4.08
> ShowMessage(FloatToStr(RoundCurrency(40.085, 2, False))); // 4.09
> end;

You get rounding up with Str() then, too.

See, if the control bit was in play - I couldn't get banker's rounding with
this routine - because it relies on Round which relies on the processor.

The Orpheus control uses Str() - ... - thanks for the feedback - I'll have
to see what those guys come back with.

Do you know why Str() rounds up instead of obeying the processor? Does it
use (a) different instruction(s)?

0 new messages