Правильный перевод double в int

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Yurij Izyumov
43139
Yurij Izyumov  

Я понимаю что тема наверно всем уже приелась с этими double, но тем не менее вопрос немного другой

почему число double умноженное на 100000 к примеру может быть равно совсем другому числу как если бы просто переставить запятую на пять знаков выше

пример : 

1.31044*100000 = 131044 и 1.31045*100000 = 131044
1.31001*100000 = 131000 и 1.31*100000 = 131000

как такое вообще может быть ? между числами разница в 1 пункт а их умножение на 100000 - равны 

я так понимаю что возможно цена какая то  в базе при расчете видимо не совсем равна тому значению, которое выводится по умолчанию, возможно там больше знаков после запятых

но никак не могу увидеть собственно этот момент NormalizeDouble ничего не даёт

а мне необходимо посчитать число пересечений между одной ценой - на истории с точностью до пункта, по этому взял привёл цену к целому, и в массив скидываю по пунктам +1 в каждую ячейку

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

приложу тестовый скрипт, который надо запустить на графике M1 ? и тогда сами увидите

double pr = Low[1];
for(int i=2;i<500;i++){
   for(int x=501;x<Bars(_Symbol,PERIOD_CURRENT)-1;x++){
      if((int)(Low[i]*MathPow(10, _Digits))==(int)(Low[x]*MathPow(10, _Digits))){
         if(Low[i]!=Low[x]){
            Print((string)Low[i]+"*"+(string)MathPow(10, _Digits)+" = "+(string)(int)(Low[i]*MathPow(10, _Digits))+"  "
            +(string)Low[x]+"*"+(string)MathPow(10, _Digits)+" = "+(string)(int)(Low[x]*MathPow(10, _Digits)));
         }
      }
   }
}

Как можно точнее переводить double в int ?

Файлы:
test.mq4 3 kb
Artyom Trishkin
Модератор
53473
Artyom Trishkin  
Yurij Izyumov:

Я понимаю что тема наверно всем уже приелась с этими double, но тем не менее вопрос немного другой

почему число double умноженное на 100000 к примеру может быть равно совсем другому числу как если бы просто переставить запятую на пять знаков выше

пример : 

как такое вообще может быть ? между числами разница в 1 пункт а их умножение на 100000 - равны 

я так понимаю что возможно цена какая то  в базе при расчете видимо не совсем равна тому значению, которое выводится по умолчанию, возможно там больше знаков после запятых

но никак не могу увидеть собственно этот момент NormalizeDouble ничего не даёт

а мне необходимо посчитать число пересечений между одной ценой - на истории с точностью до пункта, по этому взял привёл цену к целому, и в массив скидываю по пунктам +1 в каждую ячейку

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

приложу тестовый скрипт, который надо запустить на графике M1 ? и тогда сами увидите

Как можно точнее переводить double в int ?

Попробуйте считать нормализованную разницу между двумя double: NormalizeDouble(d1-d2,Digits()) и из полученной разницы выделяйте количество пунктов делением на Point()

Dmitry Fedoseev
56925
Dmitry Fedoseev  
   double x1=1.31044*100000;

   double x2=1.31045*100000;
   

   Alert((x1==x2));

Получается false (так что вывод неверный в начальном посте).

Вообще надо округлять перед присваиванием результата расчета в переменную int или нормализовать по 0.

Taras Slobodyanik
36703
Taras Slobodyanik  
int x = int (Ask / _Point);
Dmitry Fedoseev
56925
Dmitry Fedoseev  
Taras Slobodyanik:

Округлять сначала надо.

Alexander Bereznyak
31253
Alexander Bereznyak  

надо так

Print((string)(int)MathRound(1.31045/_Point));
Print((string)(int)MathRound(1.31044/_Point));
Yurij Izyumov
43139
Yurij Izyumov  

благодарю ))))) заработало 

      if((int)NormalizeDouble(Low[i]*MathPow(10, _Digits),0)==(int)NormalizeDouble(Low[x]*MathPow(10, _Digits),0)){

видимо куда то до этого не туда вставлял NormalizeDouble

Scriptor
64070
Scriptor  
Yurij Izyumov:

благодарю ))))) заработало 

видимо куда то до этого не туда вставлял NormalizeDouble

Не верное сравнение. Сравнивать необходимо нормализованную разницу. При сравнении двух нормализованных чисел, результат получается опять не нормализованный.

Dmitry Fedoseev
56925
Dmitry Fedoseev  
Scriptor:

Не верное сравнение. Сравнивать необходимо нормализованную разницу. При сравнении двух нормализованных чисел, результат получается опять не нормализованный.

Серьезно? Разве разницу сравнивают не для экономии?

Алексей Тарабанов
9792
Алексей Тарабанов  
  double x1=1.31044*100000;

   double x2=1.31045*100000;
   

   Alert((x1==x2));Семен 
Dmitry Fedoseev:

Получается false (так что вывод неверный в начальном посте).

Вообще надо округлять перед присваиванием результата расчета в переменную int или нормализовать по 0.

Семен Семенович ... 

Сравнение двух вычисляемых double на равенство ... Кю

Алексей Тарабанов
9792
Алексей Тарабанов  
Yurij Izyumov:

Я понимаю что тема наверно всем уже приелась с этими double, но тем не менее вопрос немного другой

почему число double умноженное на 100000 к примеру может быть равно совсем другому числу как если бы просто переставить запятую на пять знаков выше

пример : 

как такое вообще может быть ? между числами разница в 1 пункт а их умножение на 100000 - равны 

я так понимаю что возможно цена какая то  в базе при расчете видимо не совсем равна тому значению, которое выводится по умолчанию, возможно там больше знаков после запятых

но никак не могу увидеть собственно этот момент NormalizeDouble ничего не даёт

а мне необходимо посчитать число пересечений между одной ценой - на истории с точностью до пункта, по этому взял привёл цену к целому, и в массив скидываю по пунктам +1 в каждую ячейку

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

приложу тестовый скрипт, который надо запустить на графике M1 ? и тогда сами увидите

Как можно точнее переводить double в int ?

Каждое значение  типа double - это немножко не то, что отображается. Разницу (+ или -) обозначим Е. Умножение Е на достаточно большое число (100000, к примеру) может заметно повлиять на результат, после чего А*100000 может стать похожим на (В+n)*100000. В близко к А. 

Как с этим бороться - в первую очередь, зависит от того, чего Вы хотите. Может - нормализация, может - просто 0.5 прибавить и дробную часть обрезать. Как ни банально, даже в этой простой ситуации нет универсального решения, нужны детали. 

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий