【问题标题】:Why is an information in my printf() function incorrect in MQL4?为什么我的 printf() 函数中的信息在 MQL4 中不正确?
【发布时间】:2016-11-18 04:05:57
【问题描述】:

尽管我的编码是正确的,但我的打印格式却给了我随机的答案。我试图在交易入场前显示前两个蜡烛条的蜡烛条长度。这是我使用的编码。

PCL1 & PCL2 是相关的字段条目。它们除以_Point 以提供整数格式。

PCL2 = 上一个烛台长度,Shift 2

PCL1 = 上一个烛台长度,Shift 1

在这个例子中,我专注于 Shift2 烛台

Short_Bull_2_Close   =  iClose( Symbol(), 0, 2 );
Short_Bull_2_Open    =  iOpen(  Symbol(), 0, 2 );
CandleBody_2         =  ( Short_Bull_2_Close - Short_Bull_2_Open );
                     // Gives the Candlebody length in pips.

这是我的 printf() 编码:

printf( "PCL1 [%d] PCL2 [%d]", CandleBody_1 / Point,
                               CandleBody_2 / Point
        ); // ___________________________________________________________  SELL//

但是,我得到的只是图片和突出显示的..

【问题讨论】:

    标签: mql4 metatrader4


    【解决方案1】:

    1) MQL4 是一种强类型语言(声明在变量的任何使用之前)
    + MQL4 具有数字“规范化”的历史特征

    假设(cit.)“它们除以_Point得到一个整数”不成立。

    一旦在源代码中将任何数字声明为 double

    double upFractal = 0.0,
           dnFractal = 0.0;
    

    MQL4 编译器以 IEEE-754 浮点数表示形式永远处理这些数字,并在该数字进入的任何算术运算上调用特定的操作子版本。原因很简单,double的处理方式与(New-MQL4.56789float不同,多于 int 等。 IEEE-754 中表示的一些数字在定义上是不精确的,有些可能保持精确(如果它们恰好是 2 的直接幂并且仍然处于“原始”状态(尚未被任何算术破坏)操作,这将在它们的二进制表示中引入不可避免的不精度))。

    为什么不精确?
    为什么无法避免?

    对于非处女数,二进制表示可能会产生无限长的值描述。相反,MQL4 中任何值的存储都被限制在 { 1 | 4 | 8 } 字节的内存空间中,因此无限表示被不可避免地削减了一些距离,引入一个主体 im-precision ,表示为:

    DBL_EPSILON ~ 2.2204460492503131e-016
    FLT_EPSILON ~ 1.192092896e-07
    除此之外,任何两个以 IEEE-754 二进制格式表示的数字都将编译后的代码视为“相等”,即使它们在原则上并不相等,这只是由于 IEEE-754 格式固有的不精确性。

    确实出于历史原因,double 键入的值应该总是被 NormalizeDouble() 转换,如果想将这些值发送到 MetaTrader 服务器端处理和/或在交易会上比较值地。

    2) 使用 {double | int }- 类型变量的 MQL4 操作

    如果已将变量声明为 double,则它将永远保持为 double
    如果已将变量声明为 int,那么即使是 int/3 也将保持为 int,忽略除法运算的小数积(这有时会导致 MQL4 编码人员不那么细心)。

    同样适用于上面的初始假设会产生一个惊喜,double/double -> double 即使在某些情况下,除法也可以令人满意地视为 ( 几乎 ) 整数。所以永远不要假设类型转换仅通过操作数的值发生。

    为此,有两种语法支持:

    • 显式转换函数int( ... )double( ... )
    • 内联 typecast 指令 ( (int) CandleBody_1 / _Point )

    结语:(......自定义指标设计者必读,CPU 性能会扼杀)

    如上所述,调用 (int) NormalizeDouble(...) 是一派胡言(远远超出了腰带 + 吊带的范式),首先,作为历史上的内置函数 NormalizeDouble 仍然返回 double,因此一旦它仍然产生double,就可以从花费CPU来处理数字中获得零收益,接下来因为double_Point的除法非常昂贵且效率低下,与事实相比,_PointDigitsint 值通过1 / 10^Digits 的公式相关——因此,在不花费可避免的 CPU 周期的情况下,进行转换的最快和最干净的方法是 乘法 ...
    是的,
    从快速高效处理的计算机方面,最好的是
    int( MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs * CandleBody_1 ),
    re - 使用常量
    int MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs = MathPow( 10, Digits );

    【讨论】:

      【解决方案2】:

      你必须转换成整数,你可能认为你得到一个等价于整数的实数,但转换器不这么认为。

      printf("%d",  (int)NormalizeDouble(CandleBody_2/Point,0) );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-28
        • 1970-01-01
        • 2021-12-15
        相关资源
        最近更新 更多