为什么我的 printf() 函数中的信息在 MQL4 中不正确?

Why is an information in my printf() function incorrect in MQL4?

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

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

PCL2 = 先前的烛台长度,偏移 2

PCL1 = 先前的 Candle Stick 长度,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//

然而,我得到的只是如图所示并突出显示..

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

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

1) MQL4 是一种强类型语言(声明先于变量的任何使用)
+ MQL4 具有数字的历史特征"normalisation"

An assumption (cit.) "They are divided by _Point to give an integer" does not hold.

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

double upFractal = 0.0,
       dnFractal = 0.0;

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

为什么不精确?
为什么不可避免?

对于非原始数字,二进制表示可能会产生无限长的值描述。相反,在 MQL4 中任何值的存储被限制为 { 1 | 4 | 8 }-内存字节-space 因此无限表示是 un-avoidably 切入一段距离,引入一个principal im-precision ,表示为:

DBL_EPSILON~2.2204460492503131e-016
FLT_EPSILON~1.192092896e-07
超过它的任何两个数字,以 IEEE-754 二进制格式表示,将编译代码视为 "equal",即使它们主要不相等,只是由于 IEEE-754 格式固有的 im-precision。

确实出于历史原因,double 键入的值应该总是 NormalizeDouble() 转换,如果要将这些值发送到 MetaTrader 服务器端处理 and/or 在公平的基础上比较价值。

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 仍然 returns double,因此一旦它仍然产生 [=13],花费 CPU 来处理数字提供零收益=],接下来作为_Pointdouble值的除法是非常昂贵和低效的,相比​​之下,_Pointint的值相关Digits 通过 1 / 10^Digits 的公式——所以最快和最干净的转换方法是 MULTIPLICATION,无需花费可避免的 CPU 周期...
是的,
从计算机端的快速高效处理来看,最好的是
int( MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs * CandleBody_1 )
重复使用常量
int MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs = MathPow( 10, Digits );