Speed of execution of the functions ceil(),round(),floor() - page 6

 
Nikolai Semko:

I already wrote about it here.

ok. as i understand you are writing within this terminal and within the given accuracy, you are not interested in porting and running the code on any other device or platform.

Best regards.

P.S. A good programmer should understand that the hardware and the program may change and you need to avoid bugs in the future.
 
Andrey Kisselyov:
If you are writing within the limits of the given terminal and within the limits of its accuracy, the porting and operation of the code on any other device or platform is of no interest to you.

Sincerely.

Exactly. We are talking about MQL5 (perhaps MQL4 as well - I haven't checked). And the code within classes or algorithms will be perfectly transferable within MQL. But it will also work in C++. I already have some examples.

 
Andrey Kisselyov:

P.S. A good programmer must understand that the hardware and the program may change and it is necessary to avoid errors in the future. With a task like yours, you may not be able to easily find an error in a function that you will consider infallible at that time.
In this situation it is impossible to even imagine the changes you are talking about. What might change with the mathematics of calculating (int)(x+0.5)? Will it stop discarding the fractional part or what?
 
Nikolai Semko:
In this situation, it is impossible to even imagine the changes you are talking about. What can change with the mathematics of calculating (int)(x+0.5)? Will it stop dropping the fractional part?

For example, a new data type will be introduced ...

 
STARIJ:

For example, a new data type will be introduced ...

))) Yes, but the code will stop working if the old data type is cancelled....
 
I'm talking about this mess.
y=(int)(x+0.9999999999999997);

Let's take as an example:
if you change even the bitness of the machine, you change to 64 bits and the accuracy of the machine has increased, your formula will stop working as the accuracy of the machine will be much higher than you are setting in your error.

With respect.

P.S. there may be other options where your formula will fail on a range of numbers. constantly adjusting error from switching to a different machine, or changes in compiler, which you are not informed, or when you change the representation of numbers in the machine, or from cutting a fractional part of the number when compiling a new version of the terminal ... You don't know what can change, and I don't think it's a good idea to do an IF or suffer to guess what's going to happen by writing an error over and over again...

I think that's something to think about.

 
Andrey Kisselyov:

...

P.S. double by definition cannot be an integer, the representation of a number in machine memory will not change.

Perhaps you're saying that double is not an integer data type, not that you cannot store a number with an integer value in a variable of the double type? An integer double can have an integer value.

 

Found a simple explanation of the difference between rounding implemented in computers and simple post-stack truncation. Fourteen years old, http://delphimaster.net/view/14-10885/all:

Tolik(2003-08-13 11:04) [11].

Such rounding is accepted in accounting. So, tax office also applies this rounding, so everything should add up, at least on paper :))



DiamondShark(2003-08-13 11:20) [12]

Oh-ho-ho... Again.
Suppose we have a distribution of numbers close to uniformly random. Then by "arithmetic" rounding we have:

The number Uncertainty
0 0
1 -1
2 -2
3 -3
4 -4
5 +5
6 +4
7 +3
8 +2
9 +1

As can be easily seen, if there is a large array of numbers that then need to be added up (totals for document items, account balances, etc.), then the "arithmetic" rounding will accumulate a systematic error with the expectation
0.5*10^n * 0.1 * N
where:
n -- decimal weight of digit to which rounding is performed (to two digits n=-2, to integers n=0, etc.)
0.1 is probability of each digit
N is a number of integers in an array

In order to equalize error probabilities it is necessary to compensate the only uncompensated (see table above) error +5. This is done by artificially splitting it into two equally likely +5 -5 depending on the parity of the previous digit.

Incidentally, there is a check box in the FPU status word which controls the rounding mode (arithmetic/accounting).


End quote.

Another one, http://delphimaster.net/view/15-1340952214/all:"as the average user (manager/accountant) can't explain why rounding 12.5 and 13.5 - gives different results."


When giving the user "accelerated" versions of rounding functions it has to be strongly warned that they give rise to an increased error when adding. This error will have to be carefully evaluated in very different situations. It's dangerous, it's fraught with error accumulation. I find it hard to think of an example where rounding is so important that you can forget about the errors it accumulates.

Округление чисел. Неужели ТАК правильно???
  • delphimaster.net
3-10545           Kati                  2003-08-12 10:13  2003.09.04   обновление SQL запроса 14-10898          kalishenko            2003-08-14 20:09  2003.09.04   Win2000 Server и доступ в Интернет 1-10692           lww                   2003-08-20 10:30  2003.09.04   Как написать dll для 1С? 1-10813           koks                  2003-08-20...
 

Andrey Kisselyov:
я говорю про вот это безобразие

y=(int)(x+0.9999999999999997);

All right, gentlemen, you've made your point. I'll change the ceil function for you specially:

y=ceil(x);  ->  y=(x-(int)x>0)?(int)x+1:(int)x;
или через дефайн:
#define _ceil(x) (x-(int)x>0)?(int)x+1:(int)x

This variant is 25-50% slower than variant:y=(int)(x+0.9999999999999997); but it is maximally correct, works for negative integers and is 3 times faster than ceil(x).

But myself, as a commoner and failed, I'll use the variant with nines, because I consider all your arguments boring and for me, someone who has been programming in assembler for a long time, and therefore knows what happens to the code after compilation, it's too much - to put checks where you can do without them.

 

A variant for positive and negative numbers:

#define _ceil(x) (x-(int)x>0)?(int)x+1:(int)x
#define _round(x) (x>0)?(int)(x+0.5):(int)(x-0.5)
#define _floor(x) (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x
This seems to be a full-fledged replacement for ceil(),round(),floor(), which gives a speed advantage of 3-4 times.
Reason: