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

Does Str() round up for you?

5 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