Это не ошибка, а особенность плавающей арифметики. В результате деления числа с плавающей точкой d1 на 7000 получилось число 15.000000000000002
Это не ошибка, а особенность плавающей арифметики. В результате деления числа с плавающей точкой d1 на 7000 получилось число 15.000000000000002
Может и так, но ведь тип double в mql может содержать в себе максимально 8 цифр после запятой, и при выводе например этого числа в строку после точки получается как раз 8 нулей, и потом, почему получилось такое число? ведь должно быть ровно 15, во всяком случае на языке C++ и шарпе получается всегда все точно до скольки бы число не округлялось...
Может и так, но ведь тип double в mql может содержать в себе максимально 8 цифр после запятой
//+------------------------------------------------------------------+ //| up to 16 digits after decimal point | //+------------------------------------------------------------------+ string DoubleToStrMorePrecision(double number,int precision) { double rem,integer,integer2; double DecimalArray[17]={ 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0, 100000000000.0, 10000000000000.0, 100000000000000.0, 1000000000000000.0, 1000000000000000.0, 10000000000000000.0 }; string intstring,remstring,retstring; bool isnegative=false; int rem2; //---- if(precision<0) precision=0; if(precision>16) precision=16; //---- double p=DecimalArray[precision]; if(number<0.0) { isnegative=true; number=-number; } integer=MathFloor(number); rem=MathRound((number-integer)*p); remstring=""; for(int i=0; i<precision; i++) { integer2=MathFloor(rem/10); rem2=NormalizeDouble(rem-integer2*10,0); remstring=rem2+remstring; rem=integer2; } //---- intstring=DoubleToStr(integer,0); if(isnegative) retstring="-"+intstring; else retstring=intstring; if(precision>0) retstring=retstring+"."+remstring; return(retstring); }
Может и так, но ведь тип double в mql может содержать в себе максимально 8 цифр после запятой
Это не ошибка, а особенность плавающей арифметики. В результате деления числа с плавающей точкой d1 на 7000 получилось число 15.000000000000002
Это не ошибка, а особенность плавающей арифметики. В результате деления числа с плавающей точкой d1 на 7000 получилось число 15.000000000000002
Вопрос погрешностей, сравнения чисел и результатов операций с вещественными числами постоянно всплывает на наших форумах. Вот одно из детальных объяснений погрешностей:
Mak 08.06.05 15:41
Еще как могут - и Вы это как раз показали своим примером. Вопрос "как это может появиться?" является теорией, а результат "математические(именно математические, а не только деление/умножение) операции с вещественными числами дают погрешности" - является суровой правдой жизни.Погрешность для +/- с плавающей арифметикой будет +/- 1-2 эпсилон (или +/- 1-2 эпсилон * Макс(А,В)). Причем чем больше вычислений, тем больше накапливается ошибка.
Эпсилон - это примерно значение младшего разряда мантисы числа.
В языках даже такая константа бывает (в Си кажется есть).
Для double она примерно равна 10 в минус 14 степени.
Причин как минимум 2.
1. Вещественные числа в компе всегда представляются в виде дробного числа.
Т.е. в виде М * 2^Р, где М - мантиса, |M| < 1.0, а Р - порядок, целое со знаком.
Таким способом нельзя точно представить число, все что не влазит в мантису отбрасывается.
2. Числа представляются в двоичной системе, и если мы напишем 1.1 и в десятичной это выглядит просто, то в двоичной будет выглядеть намного сложнее - может получиться периодическая дробь например, которая будет округлена размером мантисы.
В результате может оказаться что 1.1 + 2.2 не равно 3.3
Мы записали в десятичной системе, а в компе они представляются в двоичной системе и в нейже выполняются операции.
Это общая проблема всех компов и всех языков.
Проверять вещественные числа на равенство всегда некорректно (за очень редким исключением).
Равенство можно проверить только с некоторой точностью.
И сделать это можно только так
MathAbs(X-Y) < precision
Для примера в начале ветки precision <= 0.0001
Это не ошибка, а особенность плавающей арифметики. В результате деления числа с плавающей точкой d1 на 7000 получилось число 15.000000000000002
<?
$i1 = 140579;
$i2 = 35579;
$d1 = $i1 - $i2;
echo Ceil($d1 / 7000);
?>
Результат = 15.
Причём тут интел (или амд)?
<? $i1 = 140579; $i2 = 35579; $d1 = $i1 - $i2; echo(gettype($d1 / 7000)); echo Ceil($d1 / 7000); ?>
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Билд терминала 211.
Замечена ошибка в функции MathCeil() при работе с типами данных (или в логике округления типов):
следующий код возвращает 16, а должно быть 15
void start() {
int i1 = 140579;
int i2 = 35579;
double d1 = i1 - i2;
Comment(MathCeil(d1 / 7000));
}
а если просто вывести
Comment(MathCeil(15));
что по сути дела одно и тоже, что и выше, то будет уже 15