И снова о сравнении двух double - страница 3

 
Ну вы возмите какое нибудь число к примеру 1.6 и присвойте это значение к float и double и посмотрите что показывает отладчик в VS для этих двух чисел.
Если вы умножаете и делите два числа типа float с определённым количеством значащих цифр после запятой а потом записываете в double результат то какая разница. Для EURUSD это будет 4 цифры после запятой. От представления цен в виде float я думаю было бы больше плюсов чем минусов.
 
VladislavVG:
elritmo:
А почему разработчики выбрали тип double. Я посмотрел в отладчике VS и увидел такую штуку
Если в в программе делаю присвоение явно
double dVar = 1.3
то отладчик показывает значение dVar 1.299999999....
Если же
float fVar = 1.3
то вижу в отладчике, что значение fVar 1.30000

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

А скаких пор экранное представление числа (то, что Вы видите при распечатывании, в том числе и то, что Вам показывает отладчик) связано только с точностью храниения? По секрету - оно в основном связано с форматом вывода этого числа ;). Возьмите эксел - там вообще целочисленныне значения можно как дату представить.

Успехов.
Ну а почему в тладчике выводит для дабл 1.299999999... а для флоат 1. 30000.. собственно столько сколько и присвоили.
Я вообще то в этом вопросе тоже плохо разбираюсь :). Так попробовал немного поэксперементировать. Надо будет прочесть файл с ценами во флоты и в даблы и сравнить потом представления попробовать сравнить числа которые по идеи должны быть равны судя по значениям в файле и в переменных типа double и float.
Вы это пробовали делать?
 
elritmo:
Ну вы возмите какое нибудь число к примеру 1.6 и присвойте это значение к float и double и посмотрите что показывает отладчик в VS для этих двух чисел.
Если вы умножаете и делите два числа типа float с определённым количеством значащих цифр после запятой а потом записываете в double результат то какая разница. Для EURUSD это будет 4 цифры после запятой. От представления цен в виде float я думаю было бы больше плюсов чем минусов.

Увы, это не так. Форматы данных различаются по размеру мантиссы и диапазону. Если для хранения самих данных флоат хватает, то любой алгоритм, где есть операция деления будет давать погрешность. Если, например, считаете экспоненциальный мувинг, то, поскольку там текущее значение зависит от предыдущих, погрешность будет прямо пропорциональна длине выборки, на которой производятся расчеты. Еще раз: то, что Вы видите в отладчике - это скорее всего результат того, что форматы вывода числел с плавающей точкой для типов флоат и дабл разные, а не следствие большей точности числа типа флоат (точность и диапазон флоат меньше).

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

Успехов.
 
eritmo, Вы категорически неправы.

Когда я это говорю, то знаю, что у меня за плечами куча лет работы, пройденных граблей и исправленных ошибок из-за самых мелочей именно из-за точности представления и округления вещественных чисел. И сама мысль заменить double на float - это самоубийство.

Сначала Вы видите 1.3, а потом оказывается, что Вам достаточно 4х знаков! Конечно же, если думать о точности до четвертого знака, то сойдет. Только вот это никак не подойдет ни банкам, ни дотошным трейдерам, которые тут же укажут нам на расхождение в шестом знаке у сотни индикаторов. А уж какой пир устроят недоброжелатели и конкуренты! :)))

Я рекомендую Вам почитать про суть хранения данных во float и double - гугль всегда к услугам.
 

Вы это пробовали делать?

Еще раз - то, что запишется в файл не связано с точностью хранения числа в памяти. Точнее, связанно только опосредованно. Если нужно вывести числа в файл (текстовый, не бинарный), то правильно использовать DoubleToStr() с желаемой точностью и записывать строковую переменную. В МКЛ это может заменить форматы вывода (даже если разработчики этого не предусматривали, хотя я не представляю пока для чего еще эту функцию можно использовать).

Успехов.
 
VladislavVG:

Вы это пробовали делать?

Еще раз - то, что запишется в файл не связано с точностью хранения числа в памяти. Точнее, связанно только опосредованно. Если нужно вывести числа в файл (текстовый, не бинарный), то правильно использовать DoubleToStr() с желаемой точностью и записывать строковую переменную. В МКЛ это может заменить форматы вывода (даже если разработчики этого не предусматривали, хотя я не представляю пока для чего еще эту функцию можно использовать).

Успехов.
Ну я да сделал скоропостижные выводы о том что мне показал отладчик. Я конечно понимаю что при преобразовании в строки и наоборот вещественных чисел может быть округление. Получил массив rates в dll и вижу что в частном случае для EURUSD после четвёртого знака после запятой для цен какие то значения и к примеру
1.2365 будет 1.23649999... или 1.2373 как 1.2373000000000001 . Значит сравнение цен может дать ошибку я думаю. Вот и подумал что раз мне отладчик показывает
столько сколько я присвоил значение значит представление в виде флоат сэкономило бы память и при сравнении цен не надо было бы нормализовать чтобы округлить до нужного нам знака цены котрые записаны в массиве Rates.
 
elritmo:
Получил массив rates в dll и вижу что в частном случае для EURUSD после четвёртого знака после запятой для цен какие то значения и к примеру
1.2365 будет 1.23649999... или 1.2373 как 1.2373000000000001 . Значит сравнение цен может дать ошибку я думаю. Вот и подумал что раз мне отладчик показывает
столько сколько я присвоил значение значит представление в виде флоат сэкономило бы память и при сравнении цен не надо было бы нормализовать чтобы округлить до нужного нам знака цены котрые записаны в массиве Rates.

По поводу получения массивов рейтов. Я делаю проще - объявляю свои массивы даблов (статически размещенные) и копирую туда данные. Потом передаю все это по ссылкам с передачей количества копированных баров. В С принимаю как адреса (указатели). Никаких сюрпризов. Это уже не раз обсуждалось.
И еще, если для сравнения цен использовать нечто типа if(MathAbs(Close[i]-Close[i+1])<0. 5*Point) {....... }, то сюрпризов не будет ни при каком способе хранения - это стандартный способ сравнения чисел с плавающей точкой - и нормализовать ничего не нужно. Конечно, возможны варианты под оператором if() в зависимости от поставленной задачи, но сам принцип остается: сравнивается не число с числом, а разность с погрешностью ....

Успехов.
 
Я ну а я перенаправляю рейты в dll как в примере у MT всё работает тоже но рейты для EURUSD после 4 знака не 0 а какие то значения.
А у вас чт оне так получается? Ну такой подход у меня сразу в уме возник if(MathAbs(Close[i]-Close[i+1])<0.5*Point) {....... } То есть сравнение в доверительном интервале значений. я просто подумал что раз уже такие грубы допущения предполагаем то можно и float использовать чтобы сэкономить мамять для больших объёмов исторических данных. Ну и возможно что нет мусора после 4 знака после запятой для EURUSD, а идут нули как и должно быть (но не уверен - сделал вывод о том что мне показал отладчик в VS).
 
Renat:
float имеет гораздо меньшую точность по сравнению с double. А на важных расчетах, касающихся денег, нужно использовать максимальную точность.
rifat:
Тип float и тип double дают погрешности в связи с тем, что вещественные числа в памяти компьютера представляются не точно (тип целых чисел представляется в памяти компьютера точно)
IMHO именно поэтому самый адекватный тип данных для хранения денежных значений - decimal из C#. В этой структуре хрянятся до 38 десятичных цифр и позиция точки.
 
Матоперации к примеру double dRes = (Close[0] - Close[4]) *1.5f / 1.34 давали бы одинаковое значение будь у нас
double Close[] либо float Close[] для матопераций предварительно вещесвенное значение преобразуется к double особенно если хотябы одна константа или переменная у нас double
вот я и подумал какой смысл хранить параметры баров в double тогда раз они всё равно в вычислениях преобразуются к double сначала и дальше оперирует с double
Если на вход математической функции передать 1.2450 или 1.2450000000. .. то разницы нет потому как в первом случае float 1.2450 преобразуется для вычислений к double 1.24500000.. но зато сами котировки можно хранить как float что сэкономило бы память в несколько раз.
Но это так философские рассуждения на отвлечённые темы ;).
Причина обращения: