Errors, bugs, questions - page 107

 
Yedelkin:
Simpleton, I followed the same way, but used explicit conversion to int type. I assumed that the maximum possible lot size will be limited either by broker/dealer, or by the size of my own funds. So using int should be enough. Do you think there are any pitfalls in this approach (rounding from the bottom using int)?

For real trading, probably, yes, int/uint is enough.

But if you run it in a tester, it may not be enough for some experiments.

There are no pitfalls, besides possible next glitches in MQL5 implementation, if we guarantee that the integer N from the formula will fall within the range 0...INT_MAX and therefore we will not have an overflow. That is, replace check

tmp < ULONG_MAX * stepvol

to

tmp < INT_MAX * stepvol

Actually the int type is signed and half of its possible values lie in the range of negative numbers, while here they will always be non-negative. It is irrational to use int when there is an unsigned uint that has the same size but twice the range in the non-negative area. Therefore, if we are going to use int/uint, it is better to use uint and replace the check with uint, respectively:

tmp < UINT_MAX * stepvol
 

gumgum:

#property script_show_inputs

Thanks for the tip.
 
simpleton:

For real trading, most likely yes, int/uint is enough.

..Actually, int type is signed, half of its possible values lie in the area of negative numbers, and here it will always be non-negative. It is irrational to use int, when there is an unsigned uint that has the same size but twice the range in the non-negative area. Therefore, if we are going to use int/uint, it is better to use uint and replace the check with uint, respectively:

Yes, got it, thanks!
 

It's not a bug, but an interesting observation about types

What do you think 2 times 2 is, i.e. 2*2?

you think 4 maybe you're right!

OK, how about this
two hundred thousand times two hundred thousand

200000 * 200000

Any schoolboy can multiply twos and fours and add zeros and get...

40000000000.

Now let's write a simple code in the language of the machine.

long lots = 200000*200000;

note that the host type of the variable is long, i.e.
The minimum value is -9 223 372 036 854 775 808; the maximum value is 9 223 372 036 854 775 807.

Print out the total and you get

lots = 1345294336
that's a far cry from two times two and you'll get two.

I reread the help section about types and type conversions.
I did not find any information that regular numbers must be explicitly cast to the right type

so this is how it should be

long lots = (long) 200000 * (long) 200000;

alternatively, you can use additional auxiliary variables.

Документация по MQL5: Основы языка / Типы данных / Приведение типов
Документация по MQL5: Основы языка / Типы данных / Приведение типов
  • www.mql5.com
Основы языка / Типы данных / Приведение типов - Документация по MQL5
 

There's more.

If you want to retrieve and multiply by large numbers some properties....

Here's the code

long A = AccountInfoInteger(ACCOUNT_LOGIN);  // 661701
long B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
long X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);

And here is the result

L1=2322042704   L2=2322042704   L3=6617010000
A =661701        B =661701      C =661701
the inputs are the same, but the result is different
Files:
servis.mq5  2 kb
 

SHOOTER777:

And now a simple code in machine language

long lots = 200000*200000;

Note that the receiving type of long variable is long, i.e.
The minimum value is -9 223 372 036 854 775 808, the maximum value is 9 223 372 036 854 775 807.

Print the total and get

lots = 1345294336
that's a far cry from two times two and you'll get two.

I reread the help section about types and type conversions.
I did not find any information that you must explicitly cast regular numbers to a certain type.

so this is how it should be

long lots = (long) 200000 * (long) 200000;

Alternatively, you can also use auxiliary variables.

"Ordinary numbers" are constant expressions that also have a type. In this case, it is the int type.

The expression consisting of the multiplication of two subexpressions, each of them being of the int type, is also of the int type. This is where the overflow occurs.

And only then the implicit conversion from the int expression's type to the long type occurs during the variable's initialization of the long type.

Everything is clear here. By the way, each of the operands in this case does not need to be cast to the long type. It is enough to cast one, and the second will be cast implicitly.

 
SHOOTER777:

There's more.

If you want to retrieve and multiply by large numbers some properties....

Here's the code

And here is the result.

The source data are the same, but the result is different

It looks like the log and the code are mixed up. The above code works "clean". And, to get such a log, I had to make variables A and B of int or uint type, and variable X of uint type:

void OnStart()
{
int A = 661701;
int B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
uint X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);
}

/* Вывод в лог (хронология - сверху вниз):
KO      0       1 (EURUSD,M15)  00:46:28         A=661701  B=661701  C=661701
OE      0       1 (EURUSD,M15)  00:46:28         L1=2322042704   L2=2322042704   L3=6617010000
*/

And here's how the original code works:

void OnStart()
{
long A = 661701;
long B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
long X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);
}

/* Вывод в лог (хронология сверху вниз):
DL      0       1 (EURUSD,M15)  00:49:13         A=661701  B=661701  C=661701
HG      0       1 (EURUSD,M15)  00:49:13         L1=6617010000   L2=6617010000   L3=6617010000
*/

Build 314 (20 Aug 2010).

Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
  • www.mql5.com
Основы языка / Типы данных / Целые типы / Типы char, short, int и long - Документация по MQL5
 

Can you tell me, for example, if I want to get the value of some indicator. I used to get it exactly and assuredly using built-in function. Now I have to write it myself using a bunch of code, buffers, handles, etc. But that's not the point. The main thing for me is that the code becomes glitchy literally on every line, because I have to check this every line of code to make sure no error has occurred... In general, I thought that all these complexities, classes and things that were elementary but became cumbersome and inconvenient were done to increase speed, reliability, etc... I read an article about 20 signals... it says:

"You cannot access the indicator data right after its creation, as it takes some time to calculate the indicator values, therefore, it's better to create indicator handles in OnInit()".

Then there are checks for each line

"Let's check them: if there is less data than we need, it means that a copying error has occurred and further access to the array, where the data should be stored, will lead to an error. To rule this out, we will quit the function."

So, instead of speeding up, I have to do a loop (how many times?) through this function to get a result in the end... And if I need individual values of separate lines of different indicators periodically... This is a separate function for each value... That's a lot of extra variables and code...

In short, please explain, give me a link, I want to understand the meaning of all this, why it's so and not so reliable...

And it would be good if answers to such questions could be placed in the section of migration from µl4 to µl5 help or to create a relevant section on the forum, without any discussion, specifically a question and answer, with an explanation of why this is so... for example, the period is explained here in a very accessible way, and in the same way we would like to have answers to elementary questions

 
Dmitriy2:

Can you tell me, for example, if I want to get the value of some indicator. I used to get it exactly and assuredly using built-in function. Now I have to write it myself using a bunch of code, buffers, handles, etc. But that's not the point. The main thing for me is that the code becomes glitchy literally on every line, because I have to check this every line of code to make sure no error has occurred... In general, I thought that all these complexities, classes and things that were elementary but became cumbersome and inconvenient were done to increase speed, reliability, etc... I read an article about 20 signals... it says:

"You cannot access the indicator data right after its creation, as it takes some time to calculate the indicator values, therefore, it's better to create indicator handles in OnInit()".

Then there are checks for each line

"Let's check them: if there is less data than we need, it means that a copying error has occurred and further access to the array, where the data should be stored, will lead to an error. To rule this out, we will quit the function."

So, instead of speeding up, I have to do a loop (how many times?) through this function to get a result in the end... And if I need individual values of separate lines of different indicators periodically... This is a separate function for each value... That's a lot of extra variables and code...

In short, please explain, give me a link, I want to understand the meaning of all this, why it's so and not so reliable...

And it would be good if answers to such questions could be placed in the section of migration from µl4 to µl5 help or to create a relevant section on the forum, without any discussion, specifically a question and answer, with an explanation of why this is so... for example, the period is explained here in a very accessible way, so it would be good to have answers to elementary questions in the same way

Is it more reliable? Why is it unreliable to get handles at initialization? Why isn't it reliable to check availability of required data? And moreover, why is it not reliable to have checks in place?

It may not be so easy for beginners, but with time it will become clear...

 
Interesting:

More reliable? Why is getting handles at initialisation not reliable? Why is it unreliable to check for necessary data? And even more so, why is having checks not reliable?

It may not be so simple for newbies, but it will become clear in time...

Checking data doesn't degrade speed of the program as a whole, maybe only by 0.01%, I didn't do this check, and the fact that the data should be checked before using it is just for the stability of the whole system, otherwise there may be unpredictable consequences, up to terminal crash as a whole.
Reason: