Page 1 of 2

Round() slow down calculations

Posted: Tue Jul 06, 2021 9:10 am
by Victorio
Hi,

I work on optimalization of application, where milions operations calculate, and found that round() slow down processing.

I understand well ?

I have number a=1, and b=3
when c=a/b, calculate 0.33333333333 etc, but when I print nubmer I see only 0.33 when SET FIXED TO 2 for example.

But when I get variable c with number and put it to round() round calculates number with many decimals, 0.3333333 ?
If yes, this can slow down calculations.

Can I set also number of decimal places for calculations ?

I tryed val(str(c,10,4))) but this is more slower

Re: Round() slow down calculations

Posted: Tue Jul 06, 2021 5:39 pm
by sdenjupol148
Hi Victorio,

I enjoy optimizing my applications where ever I can.

If you use
a=1
b=3
SET FIXED OFF
Round(a/b, 2 )

your result should be 0.33

Are you saying you get a different outcome?

Bobby

Re: Round() slow down calculations

Posted: Tue Jul 06, 2021 6:43 pm
by Auge_Ohr
Victorio wrote: Tue Jul 06, 2021 9:10 amwhen SET FIXED TO 2 for example.
hi

as i can say : there is no
SET FIXED TO 2
help file say
SET FIXED on | OFF | <lToggle>
i use

Code: Select all

   SET DECIMALS TO 2 
   SET FIXED ON 
   ? 1/3             // 0.33 

Re: Round() slow down calculations

Posted: Wed Jul 07, 2021 1:39 am
by Victorio
sorry, yes SET FIXED ON / OFF and set decimals, I have SET DECIMALS TO 4.

But now i tested two variants

Code: Select all

starttim:=seconds()
for i=1 to 20000000
	j1:=round(c,0)
	k1:=k1+j1
next
stoptim:=seconds()
celtim1:=stoptim-starttim

starttim:=seconds()
for i=1 to 20000000
	j2:=int(c)
	k2:=k2+j2
next
stoptim:=seconds()
celtim2:=stoptim-starttim
first round need time about 11.38 sec, second function int need 7,76 sec,
this looks round need more time than Int but i cannot use int because i need round minimal to 4 decimal places.

I tryed also this : j5:=round((int(c*10000))/10000,0)
but need little more time.

At this time I must accept this , or try create own round function, but I don't believe that can create better function...

thx

Re: Round() slow down calculations

Posted: Wed Jul 07, 2021 1:53 am
by Tom
SET FIXED and SET DECIMALS have nothing to do with math precision or calculation. They are only relevant for displaying numbers.

Re: Round() slow down calculations

Posted: Wed Jul 07, 2021 2:26 am
by Tom
Hi, Victorio.

Floating point numbers in Xbase++ can have up to 16 digits behind the decimal point, which are used anyway (0.5 is 0.500000000000000 in Xbase++*). If you round a number with 16 digits behind the decimal point with parameter "2", the rounding algorithm has to walk from the last digit to the second behind the point in the worst case, since every digit may influence every digit before. This takes time, if you do it a million times. But it doesn't make calculation any better, since all the 16 digits before and the 16 digits in front of the point are used anyway. It just may make your calculation wrong. That depends on how precise your result has to be and what rounding rules can be used.

I don't know how the rounding algorithm in Xbase++ is built, but I assume it has some optimization inside, so it doesn't walk through all digits if there can't be a digit influencing the rest anymore.

* If you SET DECIMALS TO 16, you get "0.3333333333333333" as the result of "? 1/3". If you SET DECIMALS TO 32, you get "0.333333333333333300000000000000000000"

Re: Round() slow down calculations

Posted: Wed Jul 07, 2021 4:17 am
by Victorio
Ton, thanks for confirm that mathematical operations work with full decimal places.
And you are right, when SET DECIMALS TO 32 accept only first 16 decimal places , other was 0. Its important, but not important for my calculations.

I want test some primitive algorith, for example when I need only 4 decimal places, get 4 digits and compare if < > 5 and round it fithout use function round
because need first convert number to string, this can use more time, than original round().
For experiment I test it.

Re: Round() slow down calculations

Posted: Wed Jul 07, 2021 4:26 am
by Victorio
no no, converting to string need more more time, this is not right way :naughty:

Re: Round() slow down calculations

Posted: Wed Jul 07, 2021 4:53 am
by Victorio
one idea :

Code: Select all

SET FIXED ON
SET DECIMALS TO 1

c:=1.233
cu:=int(c)
d:=c-cu			
? d
if d<0.5
	e:=cu
else
	e:=cu+1
endif
? e

c:=1.568
cu:=int(c)
d:=c-cu			
? d
if d<0.5
	e:=cu
else
	e:=cu+1
endif
? e
result if c=1.233 e will be 1 when c=1.568 e will be 2
this I need, but now I must test how time need this calculations

edit:
hmmm worse time, twice more than original round.

Ok, mission impossible :naughty: I not waste more time on it.
thanks all for advices..
Viktor

Re: Round() slow down calculations

Posted: Wed Jul 07, 2021 6:30 am
by skiman
I don't know how much decimals you want?

Just some suggestions.

for i=1 to 20000000
j2:=int(c*10000)
k2+=j2
next
k2 :=k2/10000

As I understood in your last sample, 1.2 must be one, 1.51 must be 2?
c:=1.233
cu:=int(c+0.5)
c:=1.566
cu:=int(c+0.5)