double сохраняет данные не в точном виде. Нужен ли тип данных, который будет сохранять все знаки после запятой в точном виде?
- Прошу сделать оценку советнику(пипсатору) !
- Построим мини грааль!?
- Получаем количество десятичных знаков после запятой любых чисел (не только котировок) в обход Digits() на MQL4 и MQL5
Числа double хранятся в памяти компьютера с ограниченной точностью.
Пример:
0.7000000000000001 вместо 0.7
0.0999999999999999 вместо 0.1
В некоторых языках программирования есть тип данных DECIMAL.
"Каждый из нас сталкивался с выводом в строку чисел вида 3,4999990123
вместо 3,5 или, того хуже, огромной разницей после вычислений между
результатом теоретическим и тем, что получилось в результате выполнения
программного кода."
В некоторых языках программирования есть тип данных DECIMEL.
Тип Decimal есть во всех вменяемых БД, а как еще прикажете хранить денежные величины? Ну не в double же. Странно, что в MQL, который заточен на работу с финансами, такого типа нет. Проголосовал Да.
Попутно родилась мысль сделать сласс CDecimal ))
"Каждый из нас сталкивался с выводом в строку чисел вида 3,4999990123
вместо 3,5
Я не сталкивался:
double d=3.5; Print(DoubleToString(d,10)); // результат - 3.5000000000
double - очень грамотный тип данных.
И если знать и понимать его устройство, то проблем в сравнения двух double-чисел не будет.
Приведите конкретный пример, который заводит Вас в тупик. Я найду Вам решение.
Я не сталкивался:
Надеюсь, следущий код не вызовет баттхерт ))
//http://lurkmore.to/Butthurt double d=3.5; double d2 = 0.9999995555999999999999999999999999999999999999999999999; d *= d2; d /= d2; Print(DoubleToString(d,19)); // результат - 2018.12.02 06:37:42.368 TestDouble (EURUSD,M5) 3.5000000000000001
Я не сталкивался:
double - очень грамотный тип данных.
И если знать и понимать его устройство, то проблем в сравнения двух double-чисел не будет.
Приведите конкретный пример, который заводит Вас в тупик. Я найду Вам решение.
Чего там грамотного-то? Даже древний формат сопроцессора длиной 80 бит, который был еще в Intel 8087 не поддерживает, только 64 бита. Для финансовых расчетов double нигде не применяется.
Чего там грамотного-то? Даже древний формат сопроцессора длиной 80 бит, который был еще в Intel 8087 не поддерживает, только 64 бита. Для финансовых расчетов double нигде не применяется.
А кто заставляет финансы в double считать? Считайте в long, предварительно избавившись от запятой умножением на порядок нужной точности.
В процессорах, между прочим, тип double реализован на уровне железа. Компании Intel и AMD дебилы что-ли?
Надеюсь, следущий код не вызовет баттхерт ))
и в чем тут проблема?
Что? Важен 16 знак после запятой в типе, в котором точность заканчивается на 16-м знаке?
Я не сталкивался:
double pi=M_PI; Print("pi=",DoubleToString(pi,16)); double pi_3=NormalizeDouble(M_PI,3); Print("NormalizeDouble(pi,3) = ",DoubleToString(pi_3,16)) ; double pi_8=NormalizeDouble(M_PI,8); Print("NormalizeDouble(pi,8) = ",DoubleToString(pi_8,16)); double pi_0=NormalizeDouble(M_PI,0); Print("NormalizeDouble(pi,0) = ",DoubleToString(pi_0,16)); /* Результат: pi= 3.1415926535897931 NormalizeDouble(pi,3)= 3.1419999999999999 NormalizeDouble(pi,8)= 3.1415926499999998 NormalizeDouble(pi,0)= 3.0000000000000000 */
да, все правильно.
В чем проблема то?
Вас раздражают девятки? Меня нет, т.к. я понимаю как устроен тип double.
Все верно, можете проверить:
if (3.1419999999999999 == 3.142) Print("Ok"); if (3.1415926499999999 == 3.14159265) Print("Ok");
Кстати, функция NormalizeDouble в MQL5 работает не совсем корректно, но тип double здесь не причем.
Правильное значение от NormalizeDouble(M_PI,8) = 3.1415926500000002 , а не 3.1415926499999998
это можно проверить в альтернативном варианте fxsabera здесь или моем варианте здесь
Приходит человек в магазин. Конфета стоит 0,1 доллара. Он покупает ее. Следующая конфета стоит 0,2 доллара. Следующая 0,3 доллара.
каждая последующая конфета стоит на 0,1 доллара дороже.
Он закончит покупать конфеты, когда у него уже не будет денег для покупки следующей конфеты.
Написать код и в конце вывести алерт, сколько у него осталось денег.
Посчитаем в уме: 0,1+0,2+0,3+0,4. Должно остаться 0 денег.
Напишем код с использованием чисел double:
double funds=1; int itemsBought=0; for (double price=0.1; funds>=price; price+=0.1) { funds-=price; itemsBought++; } Alert(itemsBought); Alert(funds);
Результат: 0.3999999999999999
вот такие ошибки могут появляться из-за ограниченной точности.
оригинал:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования