Board index » delphi » CL - function Round(x) - am I going mad ?

CL - function Round(x) - am I going mad ?

Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

(the same with 14,5 and 15,5; try it yourself !)

Kees

 

Re:CL - function Round(x) - am I going mad ?


Quote
Kees Lagendijk wrote:

> Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

> (the same with 14,5 and 15,5; try it yourself !)

This is one of the very sophisticated points of merchant's math.
If the previous digit is even, the # is rounded down, else up.
It is made to give some "random distribution".

The usual way to round is: Rounded := Int(Input+0.5);
or even better:
  if Input < 0.0 then
    Sign := -1.0
  else
    Sign := 1.0;
  Rounded := Sign*Int(Abs(Input)+0.5);
But this is not working properly with some values!
I often use:
  Rounded := Sign*Int(Abs(Input)+0.5000000000000001);
This seems to work better ... ;-)

The "legal" way of roundig seems to be: convert the
value to a string with Str(...) and do the rounding
with the characters, then re-convert using Val.

Franz Glaser

Re:CL - function Round(x) - am I going mad ?


AFAIK,

Round rounds to the next even number.

Rudi

PS:

To be absolutely sure, roll your own round-function.

Kees Lagendijk schrieb in Nachricht <78igfj$m6...@reader1.wxs.nl>...

Quote
>Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

>(the same with 14,5 and 15,5; try it yourself !)

>Kees

Re:CL - function Round(x) - am I going mad ?


I'm assuming you're using Delphi4 because I don't think any other version
exhibits this behaviour. The reason it does this is because be default,
64-bit integer types are used (INT64). I'm not sure the exact reason why the
rounding happens like it does, suffice to say that it does. One way to fix
it is to turn off 64-bit integers (I forget how, check the help file/manual
on how to do this...it's something like -$I) or to use something other then
integer (ie Cardinal, Word, Byte, etc...)

HTH,
-Ross Elliott

Quote
Kees Lagendijk <ksbreda@_NOSPAM_wxs.nl> wrote in message

news:78igfj$m60$1@reader1.wxs.nl...
Quote
>Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

>(the same with 14,5 and 15,5; try it yourself !)

>Kees

Re:CL - function Round(x) - am I going mad ?


There are several rounding methods. I think the one under discussion is
called "bankers rounding".
Quote
Steve Hodges wrote in message ...
>Well I was always taught that when rounding, you go to the nearest number.
>If the value is exactly in the middle you go to the even number.

>this ensures that
>1)  you do not introduce a bias
>2) there is a known rule (i.e. you don't simply toss a coin)

>I beleive it's a convention.

>Steve

>Ing. Franz Glaser wrote in message <36ACD3CB.FF05...@eunet.at>...
>>Kees Lagendijk wrote:

>>> Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

>>> (the same with 14,5 and 15,5; try it yourself !)

>>This is one of the very sophisticated points of merchant's math.
>>If the previous digit is even, the # is rounded down, else up.
>>It is made to give some "random distribution".

Re:CL - function Round(x) - am I going mad ?


Well I was always taught that when rounding, you go to the nearest number.
If the value is exactly in the middle you go to the even number.

this ensures that
1)  you do not introduce a bias
2) there is a known rule (i.e. you don't simply toss a coin)

I beleive it's a convention.

Steve

Quote
Ing. Franz Glaser wrote in message <36ACD3CB.FF05...@eunet.at>...
>Kees Lagendijk wrote:

>> Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

>> (the same with 14,5 and 15,5; try it yourself !)

>This is one of the very sophisticated points of merchant's math.
>If the previous digit is even, the # is rounded down, else up.
>It is made to give some "random distribution".

Re:CL - function Round(x) - am I going mad ?


Hmm... I checked it too (simple in Evalute/Modify dialog). Function Round
doesn't give right value for any value n*2+0.5 where n =0,1...    i.e 0.5,
2.5, 4.5, 6.5 and so on. It's bug I think. May be better ask Inprise?

Kees Lagendijk D??? ???Y?? <78igfj$m6...@reader1.wxs.nl> ...

Quote
>Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

>(the same with 14,5 and 15,5; try it yourself !)

>Kees

Re:CL - function Round(x) - am I going mad ?


Kees,

This is the documented behavior for Round(). It's called "Banker's
Rounding"; numbers ending in .5 are rounded toward the nearest even
number to statistically reduce loss due to rounding. This is actually
built into the processor.

Ken
--
Ken White

Clipper Functions for Delphi
http://members.aol.com/clipfunc

Quote
Kees Lagendijk wrote:

> Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

> (the same with 14,5 and 15,5; try it yourself !)

> Kees

Re:CL - function Round(x) - am I going mad ?


Quote
Steve Hodges wrote:

> Well I was always taught that when rounding, you go to the nearest number.
> If the value is exactly in the middle you go to the even number.

> this ensures that
> 1)  you do not introduce a bias
> 2) there is a known rule (i.e. you don't simply toss a coin)

So European Commission is biased:) They have given exact directions, how
the 300 million EU-citizens should round currencies when converted from EURO
to national currencies, and vice versa.
  From the commission documents, I can't find any reference to the rounding
rule that is mentione above. You should just always round upwards all the
decimals ending to five:
  12.335 -->12.34  13.345-->13.35    14.355-->14.36 etc.

That's why we need also some simple biased rounding functions:

function RndToFlt (const X : Extended ) : Extended;
  {Biased (?) float rounding, return float}
begin
  Result := Int(X) + Int ( Frac(X) * 2 );
end;

function RndToInt (const X : Extended ) : Integer;
  {Biased (?) float rounding, return integer}
begin
  Result := Trunc(X) + Trunc ( Frac(X) * 2 );
end;

Markku Nevalainen

Re:CL - function Round(x) - am I going mad ?


On Wed, 27 Jan 1999 00:39:06 +0200, Markku Nevalainen <m...@iki.fi>
wrote:

Quote
>So European Commission is biased:) They have given exact directions, how
>the 300 million EU-citizens should round currencies when converted from EURO
>to national currencies, and vice versa.
>  From the commission documents, I can't find any reference to the rounding
>rule that is mentione above. You should just always round upwards all the
>decimals ending to five:
>  12.335 -->12.34  13.345-->13.35    14.355-->14.36 etc.

If you have a situation where rounding to even is not desired, set the
floating-point control word before calling Round. Just be sure to
restore it after calling Round.

Set Set8087CW in the online help, or roll your own in ASM.
--
Ray Lischner (http://www.tempest-sw.com/)
Author of "Hidden Paths of Delphi 3: Experts, Wizards, and the Open Tools API"

Re:CL - function Round(x) - am I going mad ?


Ross,

Sorry... This has absolutely nothing to do with 64-bit integer types;
it's actually part of the numeric coprocessor (FPU).

Ken
--
Ken White

Clipper Functions for Delphi
http://members.aol.com/clipfunc

Quote
Ross Elliott wrote:

> I'm assuming you're using Delphi4 because I don't think any other version
> exhibits this behaviour. The reason it does this is because be default,
> 64-bit integer types are used (INT64). I'm not sure the exact reason why the
> rounding happens like it does, suffice to say that it does. One way to fix
> it is to turn off 64-bit integers (I forget how, check the help file/manual
> on how to do this...it's something like -$I) or to use something other then
> integer (ie Cardinal, Word, Byte, etc...)

> HTH,
> -Ross Elliott

> Kees Lagendijk <ksbreda@_NOSPAM_wxs.nl> wrote in message
> news:78igfj$m60$1@reader1.wxs.nl...
> >Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

> >(the same with 14,5 and 15,5; try it yourself !)

> >Kees

Re:CL - function Round(x) - am I going mad ?


On Wed, 27 Jan 1999 00:39:06 +0200, Markku Nevalainen <m...@iki.fi>
wrote:

Quote
>  From the commission documents, I can't find any reference to the rounding
>rule that is mentione above. You should just always round upwards all the
>decimals ending to five:
>  12.335 -->12.34  13.345-->13.35    14.355-->14.36 etc.

>That's why we need also some simple biased rounding functions:

>function RndToFlt (const X : Extended ) : Extended;
>  {Biased (?) float rounding, return float}
>begin
>  Result := Int(X) + Int ( Frac(X) * 2 );
>end;

>function RndToInt (const X : Extended ) : Integer;
>  {Biased (?) float rounding, return integer}
>begin
>  Result := Trunc(X) + Trunc ( Frac(X) * 2 );
>end;

Be careful using those.  It's not okay to say something like

 value := 12.335;

 rounded := RndToFloat(value*100)/100;

because the extended type can't store numbers like 12.335 exactly
(since they aren't binary fractions).  (I think it works for 12.335,
but on my machine it fails for 12.805.)

You should use the currency type (exact storage to 4 decimal places),
or always work in hundredths of euros.  (What are those called, by the
way?  cents?)

Duncan

Re:CL - function Round(x) - am I going mad ?


Quote
Duncan Murdoch wrote:

> Be careful using those.  It's not okay to say something like

>  value := 12.335;

>  rounded := RndToFloat(value*100)/100;

> because the extended type can't store numbers like 12.335 exactly
> (since they aren't binary fractions).  (I think it works for 12.335,
> but on my machine it fails for 12.805.)

> You should use the currency type (exact storage to 4 decimal places),
> or always work in hundredths of euros.  (What are those called, by the
> way?  cents?)

The problem is that with this kind of basic functions I would like to keep
compatibility also with D1, and D1 does not have TCurrency type, only
Currency datafield.

I think you can quite safely do also all the monetary calculations using
type Double, as long as you keep in mind that the decimal part can be
endless, and is somehow inaccurate. You just round the final result to 2..4
decimals, before showing it anywhere on reports or on screen, or before
saving to DB.  
I don't know how else all those D1 accounting packages could have been
built.

Markku Nevalainen

Re:CL - function Round(x) - am I going mad ?


Quote
Duncan Murdoch wrote:

> work in hundredths of euros.  (What are those called, by the
> way?  cents?)

Yeah, they are cents. Here's link to Euro pages, if you sometime later
would need more info. http://europa.eu.int/euro/html/entry.html

Markku Nevalainen

Re:CL - function Round(x) - am I going mad ?


Kees Lagendijk schrieb:

Quote
> Why does Round(12,5) results in 12 and Round(13,5) in 14 ?

> (the same with 14,5 and 15,5; try it yourself !)

> Kees

Hallo Kees

Try the following Procedure. You need a Form (Form1), three
Edit-Components (Edit1, Edit2, Edit3) and a Button(Button1).
Write in Edit1 '12,5' (or maybe you have to write 12.5) and you got two
result.
In Edit2 is the Result with Round() in edit3 is the Result  with a
formated string.

I hope This is what you need.

Christian Fahn

procedure TForm1.Button1Click(Sender: TObject);
CONST
  StrStellenHinterKomma = '0';
begin
  edit2.text :=
FloatToStr(Round(StrToFloat(Edit1.Text)));
//With 12,5 the result is 12
  edit3.text :=
format('%.'+StrStellenHinterKomma+'f',[StrToFloat(Edit1.text)]);
//With 12,5 the result is 13
end;

Go to page: [1] [2]

Other Threads