错误、漏洞、问题 - 页 107

 
Yedelkin:
傻瓜,我也是这么做的,但是用了显式转换为int类型。我假设最大可能的手数将受到经纪人/交易商的限制,或者受到我自己资金规模的 限制。因此,使用int应该是足够的。你认为这种方法(使用int从底部四舍五入)有什么隐患吗?

对于真正的交易,可能是的,int/uint就足够了。

但如果你在测试器中运行它,对于某些实验来说可能是不够的。

除了MQL5实现中可能出现的下一个故障外,如果我们保证公式中的整数N将落在0...INT_MAX的范围内,因此我们不会出现溢出,就没有任何隐患。也就是说,更换检查

tmp < ULONG_MAX * stepvol


tmp < INT_MAX * stepvol

事实上,int类型是有符号的,它的一半可能的值位于负数范围内,而在这里它们总是非负数。当有一个无符号的uint在非负数区域具有相同的大小但两倍的范围时,使用int是不合理的。因此,如果我们要使用int/uint,最好分别使用uint和用uint替换检查。

tmp < UINT_MAX * stepvol
 

gumgum:

#property script_show_inputs

谢谢你的提示。
 
simpleton:

对于真正的交易,很可能是的,输入/输出就足够了。

...实际上,int类型 是有符号的,它的一半可能的值位于负数的区域,在这里它总是非负数。使用int是不合理的,因为在非负数区域有一个无符号的uint,其大小相同,但范围是两倍。因此,如果我们要使用int/uint,最好分别使用uint和用uint替换检查。

是的,知道了,谢谢!
 

这不是一个错误,而是一个关于类型的有趣观察

你认为2乘以2是什么,即2*2?

你认为4也许你是对的!

好吧,这个怎么样
二十万乘以二十万

200000 * 200000

任何小学生都可以用2和4相乘,再加上零,得到...

40000000000.

现在让我们用机器的语言写一个简单的代码。

长手=200000*200000。

注意,该变量的主机类型为长,即
最小值为-9 223 372 036 854 775 808;最大值为9 223 372 036 854 775 807。

打印出总数,你会得到

批量 = 1345294336
这与2乘以2就能得到2的情况相差甚远。

我重读了关于类型和类型转换 的帮助部分。
我没有找到任何信息表明常规数字必须明确地被投到正确的类型中去。

所以,这就是它应该是这样的

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

或者,你可以使用额外的辅助变量。

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

还有更多。

如果你想检索和乘以大数,一些属性....。

以下是代码

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);

而这里的结果是

L1=2322042704   L2=2322042704   L3=6617010000
A =661701        B =661701      C =661701
输入相同,但结果不同
附加的文件:
servis.mq5  2 kb
 

SHOOTER777:

现在用机器语言编写一个简单的代码

长手=200000*200000。

注意,长变量的接收类型是长,即
最小值为-9 223 372 036 854 775 808,最大值为9 223 372 036 854 775 807。

打印总数,得到

批量 = 1345294336
这与2乘以2就能得到2的情况相差甚远。

我重读了关于类型和类型转换 的帮助部分。
我没有找到任何信息表明你必须明确地将普通数字投到某种类型。

所以,这就是它应该是这样的

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

另外,你也可以使用辅助变量。

"普通数字 "是常数表达式,也有一个类型。在这种情况下,它是int类型。

由两个子表达式相乘组成的表达式,每个表达式都是int类型的,也是int类型的。这就是溢出发生的地方。

而只有这样,在变量的长类型初始化过程中,才会发生从int表达式的类型到长类型的隐式转换。

这里的一切都很清楚。顺便说一下,在这种情况下,每个 操作数 不需要被转换为长类型。只要投出一个就够了,第二个将被隐含地投出。

 
SHOOTER777:

还有更多。

如果你想检索和乘以大数,一些属性....。

以下是代码

而这就是结果。

源数据是相同的,但结果是不同的

看起来日志和代码是混在一起的。上述代码 "干净 "地工作。而且,为了得到这样的日志,我不得不让变量A和B变成int或uint类型,而变量X变成uint类型

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
*/

而这里是原始代码的工作方式。

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(2010年8月20日)。

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

你能告诉我,例如,如果我想得到某个指标的值。我曾经使用内置功能准确地获得了它,并保证了它。现在我不得不自己用一堆代码、缓冲区、句柄等来写。但这不是问题的关键。对我来说,最主要的是,代码在每一行都会出现故障,因为我必须检查这每一行的代码,以确保没有发生错误......。总的来说,我认为所有这些复杂的东西、类和那些基本的但变得繁琐和不方便的东西都是为了提高速度、可靠性等等。我读了一篇关于20个信号的文章...它说。

"你不能在指标创建后立即访问它的数据,因为计算指标值需要一些时间,因此,最好在OnInit() 中创建指标句柄"。

然后,对每一行都有检查

"让我们检查一下:如果数据比我们需要的少,这意味着发生了复制错误,进一步访问应该存储数据的数组,将导致错误。为了排除这种情况,我们将退出该功能。"

所以,我非但没有加速,反而要通过这个函数做一个循环(多少次),最后得到一个结果......如果我需要不同指标的单独行的单个值定期...这是一个单独的函数,用于每个值...那是很多额外的变量和代码...

总之,请解释一下,给我一个链接,我想了解这一切的意义,为什么它是如此和不那么可靠......

而且,如果能将这类问题的答案放在从µl4迁移到µl5的帮助部分,或者在论坛上创建一个相关的部分,不做任何讨论,专门做一个问答,并解释为什么会这样,那就更好了......例如,这里 以一种非常容易理解的方式解释了这一时期,同样,我们也希望能得到基本问题的答案。

 
Dmitriy2:

你能告诉我,例如,如果我想得到某个指标的值。我曾经使用内置功能准确而有把握地得到它。现在我不得不自己用一堆代码、缓冲区、句柄等来写。但这不是问题的关键。对我来说,最主要的是,代码在每一行都会出现故障,因为我必须检查这每一行的代码,以确保没有发生错误......。总的来说,我认为所有这些复杂的东西、类和那些基本的但变得繁琐和不方便的东西都是为了提高速度、可靠性等等。我读了一篇关于20个信号的文章...它说。

"你不能在指标创建后立即访问它的数据,因为计算指标值需要一些时间,因此,最好在OnInit() 中创建指标句柄"。

然后,对每一行都有检查

"让我们检查一下:如果数据比我们需要的少,这意味着发生了复制错误,进一步访问应该存储数据的数组,将导致错误。为了排除这种情况,我们将退出该功能。"

所以,我非但没有加速,反而要通过这个函数做一个循环(多少次),最后得到一个结果......如果我需要不同指标的单独行的单个值定期...这是一个单独的函数,用于每个值...那是很多额外的变量和代码...

总之,请解释一下,给我一个链接,我想了解这一切的意义,为什么它是如此和不那么可靠......

而且,如果能将这类问题的答案放在从µl4迁移到µl5的帮助部分,或者在论坛上创建一个相关的部分,不做任何讨论,专门做一个问答,并解释为什么会这样,那就更好了......例如,这里 以一种非常容易理解的方式解释了这一时期,因此,如果能以同样的方式回答基本问题就更好了。

它是否更可靠?为什么在初始化时获得句柄是不可靠的?为什么检查所需数据的可用性并不可靠?此外,为什么有了检查就不可靠了呢?

对于初学者来说,这可能不是那么容易,但随着时间的推移,它将变得清晰。

 
Interesting:

更加可靠?为什么在初始化时获得手柄不可靠?为什么检查必要的数据是不可靠的?更有甚者,为什么有检查就不可靠呢?

对于新手来说,这可能不是那么简单,但随着时间的推移会变得清晰......

检查数据并不会降低整个程序的速度,也许只有0.01%,我没有做这个检查,事实上,在使用数据之前应该检查数据,只是为了整个系统的稳定,否则可能会有不可预知的后果,直至终端整体崩溃。
原因: