NormalizeDouble парадокс

 

добрый день!

сколько я ни читаю этот раздел справки, все не могу понять - ну ОТКУДА там возникает эта дробная единичка в конце???

Нужно иметь в виду, что нормализованное число при выводе в Журнал с помощью Print() может содержать большее количество знаков после запятой, чем вы ожидаете. Например,

   double a=76.671;             // нормализованное число с 3 знаками после запятой
   Print("Print(76.671)=",a);   // выведем его как есть
   Print("DoubleToString(a,8)=",DoubleToString(a,8)); // выведем с заданной точностью

выдаст в терминале:

 DoubleToString(a,8)=76.67100000
 Print(76.671)=76.67100000000001

 

 
transcendreamer:

добрый день!

сколько я ни читаю этот раздел справки, все не могу понять - ну ОТКУДА там возникает эта дробная единичка в конце???

Нужно иметь в виду, что нормализованное число при выводе в Журнал с помощью Print() может содержать большее количество знаков после запятой, чем вы ожидаете. Например,

   double a=76.671;             // нормализованное число с 3 знаками после запятой
   Print("Print(76.671)=",a);   // выведем его как есть
   Print("DoubleToString(a,8)=",DoubleToString(a,8)); // выведем с заданной точностью

выдаст в терминале:

 DoubleToString(a,8)=76.67100000
 Print(76.671)=76.67100000000001

 

Тип double имеет ограничения в точности, из-за этого возможны погрешности.

Рекомендую данную статью: https://www.mql5.com/ru/articles/1561

Особенности работы с числами типа double в MQL4
Особенности работы с числами типа double в MQL4
  • 2009.11.02
  • MetaQuotes Software Corp.
  • www.mql5.com
В данной заметке собраны советы по решению наиболее часто возникающих ошибок при работе с числами типа double в программах на MQL4.
 
ENSED:

Тип double имеет ограничения в точности, из-за этого возможны погрешности.

Рекомендую данную статью: https://www.mql5.com/ru/articles/1561

рекомендация понятна, спасибо

можно использовать DoubleToStr при выводе

но непонятно откуда вообще берется эта единичка!

если бы я делал деление/умножение то ОК, ясно, погрешность

но в константе? которую я сам же прописал?

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

а самое главное подрывается доверие к тому что же на самом деле хранится в double переменной!

 

Цитата из документации

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

Например, числа 0.3 и 0.7 представлены в компьютере бесконечными дробями, в то время как число 0.25 хранится точно, так как представляет из себя степень двойки.

 
stringo:

Цитата из документации

интересно...

я уже догадываюсь что дело тут не в MQL а где-то глубже на уровне стандартов 80х годов

но все равно очень странно...

такого я не встречал ни в одном прикладном языке

было бы разумно иметь на уровне самого языка MQL какие-то обходные пути

 

и все равно это не объясняет почему в приведенном ниже коде выдаются хвосты 0000000001

current=NormalizeDouble(GlobalVariableGet("Equity-"+portfolio_id),2);

text = "Positions closed at " + (string)current + " for portfolio: " + portfolio_name;

if(!automatic) MessageBox(text,""); else Print(text);

ведь я выполнил нормализацию

а число все равно с хвостом 

 
transcendreamer:

интересно...

я уже догадываюсь что дело тут не в MQL а где-то глубже на уровне стандартов 80х годов

но все равно очень странно...

такого я не встречал ни в одном прикладном языке

было бы разумно иметь на уровне самого языка MQL какие-то обходные пути

А что в этом сложного?

Если нужна точность до 4х знаков. Умножаем число на 10000 отбрасываем дробную часть и делим на 10000.

С математическими функциями mql можно ознакомиться в документации.

 

text = "Positions closed at " + (string)current + " for portfolio: " + portfolio_name;

вот тут надо DoubleTo String для current сделать и все будет нормально 

 

да, я уже понял надо принудительно округлять 

NormalizeDouble видимо не справляется с задачей

 
transcendreamer:

да, я уже понял надо принудительно округлять 

NormalizeDouble видимо не справляется с задачей

NormalizeDouble именно так и работает (и всегда так работал, начиная с самого первого MQL)

Число умножается на 10 в степени digits, переводится в целый вид (отбрасываем дробную часть), а потом делится на 10 в степени digits

Какие проблемы-то? Разрыв шаблона?

 
stringo:

NormalizeDouble именно так и работает (и всегда так работал, начиная с самого первого MQL)

Число умножается на 10 в степени digits, переводится в целый вид (отбрасываем дробную часть), а потом делится на 10 в степени digits

Какие проблемы-то? Разрыв шаблона?

разрыв шаблона в том что даже после нормализации остаются хвосты!
Причина обращения: