Абсолютное значение числа

В MQL5 API имеется функция MathAbs, позволяющая убрать у числа знак минус, если он есть. Она избавляет нас от ручного кодирования более длинных эквивалентов, например, такого:

if(x < 0x = -x;

numeric MathAbs(numeric value) ≡ numeric fabs(numeric value)

Функция возвращает абсолютное значение переданного ей числа, то есть его модуль. Аргументом может быть число любого типа. Иными словами, функция перегружена для char/uchar, short/ushort, int/uint, long/ulong, float и double, хотя для беззнаковых типов — значения и так всегда неотрицательные.

При передаче строки, она будет неявно преобразована в число double, о чем компилятор выдаст предупреждение.

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

Примеры использования функции приведены в файле MathAbs.mq5.

void OnStart()
{
   double x = 123.45;
   double y = -123.45;
   int i = -1;
   
   PRT(MathAbs(x)); // 123.45, число осталось "как есть"
   PRT(MathAbs(y)); // 123.45, знак минус ушел
   PRT(MathAbs(i)); // 1, int обрабатывается естественным образом
   
   int k = MathAbs(i);  // без предупреждения: тип int у параметра и результата
   
   // ситуации с предупреждениями:   
   // требуется конвертация double в long
   long j = MathAbs(x); // possible loss of data due to type conversion
   
   // требуется конвертация из большого типа (4 байта) в маленький (2 байта)
   short c = MathAbs(i); // possible loss of data due to type conversion
   ...

Важно отметить, что приведение знакового целого к беззнаковому не эквивалентно получению модуля числа:

   uint u_cast = i;
   uint u_abs = MathAbs(i);
   PRT(u_cast);             // 4294967295, 0xFFFFFFFF
   PRT(u_abs);              // 1

Также обратите внимание, что число 0 может иметь знак:

   ...
   double n = 0;
   double z = i * n;
   PRT(z);               // -0.0
   PRT(MathAbs(z));      //  0.0
   PRT(z == MathAbs(z)); // true
}

Наиболее показательным примером использования MathAbs является проверка двух вещественных чисел на равенство. Как известно, вещественные числа имеют ограниченную точность представления значений, которая может дополнительно деградировать в ходе длительных вычислений (например, сумма десяти значений 0.1 не дает в точности 1.0). Строгое условие value1 == value2 может давать false в большинстве случаев, когда чисто умозрительно должно бы выполняться равенство.

Поэтому для сравнения вещественных величин обычно используют запись:

MathAbs(value1 - value2) < EPS

где EPS — некое малое положительное значение, заданная точность (см. пример в разделе Операции сравнения).