Lazarus

Programming => General => Topic started by: KonradLaz on November 25, 2024, 08:48:23 pm

Title: Round in 32 bit
Post by: KonradLaz on November 25, 2024, 08:48:23 pm
why round in 64 bit mode for curr = 658125000 gives 658130000 and for 32 bit mode 658120000 ?
Title: Re: Round in 32 bit
Post by: dseligo on November 26, 2024, 02:03:28 am
I get 65812 both under 32 and 64 bit.

Maybe you should give more detail: what processor are you compiling to, what OS, FPC version, test program you use, ...
Title: Re: Round in 32 bit
Post by: jamie on November 26, 2024, 02:19:42 am
Hmm lets see.

Extended in 32 bit mode gives you a better round.

Extended in 64 bit mode gives you a worse round because its really a DOUBLE.

Try Double in both maybe?

Title: Re: Round in 32 bit
Post by: Thaddy on November 26, 2024, 11:41:05 am
In the case of currency it does not matter because the round is correct to 0.00005.
Currency is not a float, but a scaled integer.
This is not immediately obvious but you can see that from the range of comp:
https://www.freepascal.org/docs-html/ref/refsu5.html or from e.g. the Delphi documentation:
"You can use for financial calculations the Currency type. The Currency type is in essence an integer scaled by 10000 (this value allows exact division by 10). You can store four decimal digits in a Currency variable, anything that goes beyond this limit is rounded."
Which is the same in fpc;
https://www.freepascal.org/docs-html/3.0.0/ref/refsu6.html
"The currency type is a fixed-point real data type which is internally used as an 64-bit integer type (automatically scaled with a factor 10000), this minimalizes rounding errors."

So there is no round error at all, unless you perform calculations with real floats and you should avoid that.
Title: Re: Round in 32 bit
Post by: KonradLaz on November 26, 2024, 11:29:19 pm
I found something like this in the documentation:

Description
Round
 rounds
X
 to the closest integer, which may be bigger or smaller than
X
.
In the case of
.5
, the algorithm uses "banker's rounding":
.5
 values are always rounded towards the even number.



ok I wrote my own rounding function in accordance with the tax interpretation

function TaxRound(Value: Double): Integer;
begin
  if Frac(Value) = 0.5 then
    Result := Trunc(Value) + 1
  else
    Result := Round(Value);
end;
Title: Re: Round in 32 bit
Post by: Thaddy on November 27, 2024, 11:03:02 am
wrong.
you multiply by 10.000, leave out the fraction and then divide by 10.000.
Title: Re: Round in 32 bit
Post by: BrunoK on November 27, 2024, 02:08:57 pm
ok I wrote my own rounding function in accordance with the tax interpretation

Code: Pascal  [Select][+][-]
  1. function TaxRound(Value: Double): Integer;
  2. begin
  3.   if Frac(Value) = 0.5 then
  4.     Result := Trunc(Value) + 1
  5.   else
  6.     Result := Round(Value);
  7. end;
Your function should probably be symmetrical vs 0 so you might try :
Code: Pascal  [Select][+][-]
  1. function TaxRound(Value: Double): Integer;
  2. begin
  3.   if Value<0 then
  4.     Result := Trunc(Value-0.5)
  5.   else
  6.     Result := Trunc(Value+0.5);
  7. end;
Title: Re: Round in 32 bit
Post by: KonradLaz on November 28, 2024, 07:59:37 pm
wrong.
you multiply by 10.000, leave out the fraction and then divide by 10.000.

good idea, but first divide then multiply, unfortunately still for 0.5 still round to even numbers 1->2, 2->2 ,3->4, 4->4, 5->6 ...
Title: Re: Round in 32 bit
Post by: Thaddy on November 28, 2024, 09:08:44 pm
It is not only a good idea, it is also how currency works. (as per the documentation links)
Currency is a scaled integer, not a real float.
And, again, rounding with currency is fixed and it does not matter if it is 32 or 64 bit. That only happens when you are not careful and mix currency with double or single.
Title: Re: Round in 32 bit
Post by: KonradLaz on November 28, 2024, 10:12:35 pm
And, again, rounding with currency is fixed and it does not matter if it is 32 or 64 bit. That only happens when you are not careful and mix currency with double or single.

I agree, I was careless when using division /
TinyPortal © 2005-2018