Почему информация в моей функции printf() неверна в MQL4?

Мое форматирование печати дает мне случайные ответы, несмотря на то, что мое кодирование правильное. Я пытаюсь отобразить длину свечных баров предыдущих двух свечных баров до входа в сделку. Вот кодировка, которую я использовал.

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

Тем не менее, все, что я получаю, как на фото и выделено.. введите описание изображения здесь

2 ответа

Решение

1) MQL4- язык со строгой типизацией (объявление предшествует любому использованию переменной)
+ MQL4 имеет историческую особенность числа "нормализация"

Предположение (cit.) "Они делятся на _Point дать целое число " не имеет места.

После того, как любое число было объявлено double в исходном коде как:

double upFractal = 0.0,
       dnFractal = 0.0;

MQL4-компилятор обрабатывает эти числа навсегда в представлении чисел с плавающей запятой IEEE-754 и вызывает конкретную подверсию операций для любой арифметической операции, в которую входит это число. Причина проста, double имеет другую обработку, чем (Новый - MQL4.56789) float чем больше int и другие. Некоторые числа, представленные в IEEE-754, являются неточными по определению, некоторые могут оставаться точными (если они оказываются некоторой прямой степенью числа 2 и все еще находятся в "первичном" состоянии) (еще не были испорчены какой-либо арифметикой операция, которая привела бы к недопустимой точности в их бинарном представлении)).

Почему точность?
Почему нельзя избежать?
Для не девственных чисел двоичное представление может привести к бесконечно длинному описанию значения. Напротив, хранение любого значения в MQL4 ограничено { 1 | 4 | 8 } -байт пространства памяти и, таким образом, бесконечное представление неизбежно обрезается на некотором расстоянии, внося принципиальную неточность, выраженную как:

DBL_EPSILON ~ 2.2204460492503131e-016
FLT_EPSILON ~ 1.192092896e-07
за пределами которого любые два числа, представленные в двоичном формате IEEE-754, выглядят для скомпилированного кода как "равные", даже если они не принципиально равны, просто из-за присущей im I-точности формата IEEE-754.

По действительно историческим причинам, double введенные значения должны были быть всегда NormalizeDouble() конвертируется, если кто-то хочет отправить их на серверную обработку MetaTrader и / или сравнить значения на справедливой основе.

2) MQL4 операции с {double | int } - типизированные переменные

Если кто-то объявил переменную, чтобы быть double, это остается double навсегда.
Если кто-то объявил переменную, чтобы быть int даже int/3 останется int игнорируя дробные продукты операции деления (что иногда вызывает головные боли у не очень заботливых кодеров MQL4).

То же самое, примененное к первоначальному предположению выше, приводит к удивлению, что double/double -> double даже в случаях деления можно было бы удовлетворительно считать (почти) целое число. Поэтому никогда не допускайте, чтобы преобразование типов происходило только по значениям операндов.

Для этого есть два вида синтаксической поддержки:

  • явная функция преобразования int( ... ) или же double( ... )
  • встроенная директива Typecast ( (int) CandleBody_1 / _Point )

Эпилог: (... необходимо прочитать для разработчиков пользовательских индикаторов, где производительность процессора убивает)

Как сказано выше, звоня (int) NormalizeDouble(...) это двойная чепуха (далеко за рамками парадигмы пояс + подтяжки), во-первых, как исторически встроенная функция NormalizeDouble все еще возвращается double таким образом, обеспечивая нулевую выгоду от затрат процессора на сокращение чисел, если он все еще дает double, следующий как деление числа а double ценность _Point очень дорогой и неэффективный, по сравнению с тем, _Point относится к int ценность Digits по формуле 1 / 10^Digits - поэтому самым быстрым и чистым способом преобразования, не тратя процессорных циклов, которых можно избежать, является МУЛЬТИПЛИКАЦИЯ...
да,
с точки зрения быстрой и эффективной обработки на компьютере
int( MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs * CandleBody_1 ),
повторное использование константы
int MAKE_aPriceDOMAIN_VALUE_an_INT_NUM_OF_POINTs = MathPow( 10, Digits );

Вы должны преобразовать в целое число, вы можете подумать, что вы получили действительное число, эквивалентное целому числу, но конвертер так не считает.

printf("%d",  (int)NormalizeDouble(CandleBody_2/Point,0) );
Другие вопросы по тегам