Баг сложения чисел с плавающей запятой

 
void OnStart()
{
    double x = 0.7;
    x += 0.1;
    Alert(x);
}

Результат:

Результат сложения 0.7 + 0.1 

Без комментариев... Самое интересное, что глюк наблюдается только при сложении чисел 0.7 + 0.1. Во всех остальных комбинациях (0.6 + 0.1 или 0.8 + 0.1) результат получается как надо.

 
Xenon:

Результат:

 

Без комментариев... Самое интересное, что глюк наблюдается только при сложении чисел 0.7 + 0.1. Во всех остальных комбинациях (0.6 + 0.1 или 0.8 + 0.1) результат получается как надо.

Сумма действительных чисел. Результат должен быть в интервале 0,799999999999999999 - 0,8000000000000000001.

 
Vinin:

Сумма действительных чисел. Результат должен быть в интервале 0,799999999999999999 - 0,8000000000000000001.


А можно более подробно почему должен быть результат в указанном интервале, а не конкретное число? В любом языке программирования (навскидку я их знаю штук 5) будет конкретное число 0,8 (что собственно соответствует правилам математики).

И еще, раз это "корректный" результат сложения, то значит мне после каждого вычисления надо делать округление? 

 
Xenon:

А можно более подробно почему должен быть результат в указанном интервале, а не конкретное число? В любом языке программирования (навскидку я их знаю штук 5) будет конкретное число 0,8 (что собственно соответствует правилам математики).

И еще, раз это "корректный" результат сложения, то значит мне после каждого вычисления надо делать округление? 

Приведите примеры из других языков 
 

Спец. для Вас накидал в VisualStudio пример:

 

В примере язык C#. На 100% уверен, что аналогичный результат будет и в С++ и в Java. Я уже не говорю про такие высокоуровневые языки как Паскаль, Бейсик, Ада и т.д. Да и вообще, по законам математики 0.7 + 0.1 = 0.8 и никакое другое число. ЛЮБОЙ калькулятор это выдаст. Просто бред какой-то с этим MQL4....

 
Xenon:

Спец. для Вас накидал в VisualStudio пример:

 

В примере язык C#. На 100% уверен, что аналогичный результат будет и в С++ и в Java. Я уже не говорю про такие высокоуровневые языки как Паскаль, Бейсик, Ада и т.д. Да и вообще, по законам математики 0.7 + 0.1 = 0.8 и никакое другое число. ЛЮБОЙ калькулятор это выдаст. Просто бред какой-то с этим MQL4....

А теперь, внимание вопрос: "Что есть такое вещественный тип double?"
 
barabashkakvn:
А теперь, внимание вопрос: "Что есть такое вещественный тип double?"
Я отлично понимаю к чему Вы ведете и знаю, что в памяти вещественные числа по стандарту IEEE754 в двоичном виде могут быть представлены в виде бесконечной дроби. Однако... Я ни разу не встречал подобное округление в других языках программирования. Явно показан выше пример на C#. Код абсолютно аналогичный, однако результат разный
 
Xenon:
Я отлично понимаю к чему Вы ведете и знаю, что в памяти вещественные числа по стандарту IEEE754 в двоичном виде могут быть представлены в виде бесконечной дроби. Однако... Я ни разу не встречал подобное округление в других языках программирования. Явно показан выше пример на C#. Код абсолютно аналогичный, однако результат разный

Функции типа 

Print()
Alert()

выводят на печать тип double с точностью до 16 десятичных цифр после точки. Для более привычного отображения типа double на печати существует 

DoubleToString()
 
barabashkakvn:

...Для более привычного отображения типа double на печати существует...  

Я вычислял размер открываемого лота. На экран я выводил просто как тестовое сообщение. Проблему решил применением ф-ции NormalizeDouble( ... ). Я в MQL новичек, но на мой взгляд - это костыль. Ну, пусть будет фича, раз так легче...
 
Xenon:
Я вычислял размер открываемого лота. На экран я выводил просто как тестовое сообщение. Проблему решил применением ф-ции NormalizeDouble( ... ). Я в MQL новичек, но на мой взгляд - это костыль. Ну, пусть будет фича, раз так легче...
Что есть "...костыль..."? 
 

Писал советника под экзотику типа HKD/ZAR (как пример) цены 50.00001 т.е. 5 цифр после запятой. Ордера не открываются. GetLasterror выдает ошибку что-то типа 138. В новой справке такого кода нет! Внимательно почитал логи. Пишет неправильная цена. Каково же было мое удивление что цена Аск передается как 50,0000100. NormalizeDouble исправил эту ошибку. Но думаю не очень опытным прогерам это сильно осложнило бы жизнь... 

так что ваш пример это еще часть проблемы!  

Причина обращения: