为什么我的 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 来处理数字提供零收益=],接下来作为_Point
的double
值的除法是非常昂贵和低效的,相比之下,_Point
与int
的值相关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 );
尽管我的编码是正确的,但我的打印格式给出了随机答案。我试图在交易进入之前显示前两个蜡烛条的蜡烛条长度。这是我使用的编码。
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
仍然 returnsdouble
,因此一旦它仍然产生 [=13],花费 CPU 来处理数字提供零收益=],接下来作为_Point
的double
值的除法是非常昂贵和低效的,相比之下,_Point
与int
的值相关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 );