Такая работа NormalizeDouble() - это нормально?

 

Такая работа NormalizeDouble():

//+------------------------------------------------------------------+
//|                                       TEST_NormalizeDouble().mq4 |
//+------------------------------------------------------------------+
#property copyright "Vladimir"
#property link      "*"
///////////////
void start() //
{
double a,b,c;
 
a= 1234567.90000053;
b= 12345678.90000053;
c= 123456789.90000053;
////////////////////////
a=NormalizeDouble(a,1);
Print("a = ",DoubleToStr(a,8),"   Digits = 1");
b=NormalizeDouble(b,1);
Print("b = ",DoubleToStr(b,8),"   Digits = 1");
c=NormalizeDouble(c,1);
Print("c = ",DoubleToStr(c,8),"   Digits = 1");
a= 1234567.90000053;
b= 12345678.90000053;
c= 123456789.90000053;
Print("                        ");
a=NormalizeDouble(a,3);
Print("a = ",DoubleToStr(a,8),"   Digits = 3");
b=NormalizeDouble(b,3);
Print("b = ",DoubleToStr(b,8),"   Digits = 3");
c=NormalizeDouble(c,3);
Print("c = ",DoubleToStr(c,8),"   Digits = 3");
a= 1234567.90000053;
b= 12345678.90000053;
c= 123456789.90000053;
Print("                        ");
a=NormalizeDouble(a,8);
Print("a = ",DoubleToStr(a,8),"   Digits = 8");
b=NormalizeDouble(b,8);
Print("b = ",DoubleToStr(b,8),"   Digits = 8");
c=NormalizeDouble(c,8);
Print("c = ",DoubleToStr(c,8),"   Digits = 8");
   return;
}
///////////////
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: c = 123456789.90000053 Digits = 8
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: b = 12345678.90000053 Digits = 8
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: a = 1234567.90000053 Digits = 8
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30:
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: c = 123456789.90000001 Digits = 3
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: b = 12345678.90000000 Digits = 3
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: a = 1234567.90000000 Digits = 3
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30:
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: c = 123456789.90000001 Digits = 1
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: b = 12345678.90000000 Digits = 1
2008.06.29 19:26:02 TEST_NormalizeDouble() GBPUSD,M30: a = 1234567.90000000 Digits = 1


- это нормально?


Как проще избавиться от мусора в младших разрядах больших чисел, такого как 123456789.90000053 ?

 

А вот еще лучше:

2008.06.29 19:58:26 TEST_NormalizeDouble() GBPUSD,M30: c = 123456789.90000100 Digits = 6
2008.06.29 19:58:26 TEST_NormalizeDouble() GBPUSD,M30: b = 12345678.90000100 Digits = 6
2008.06.29 19:58:26 TEST_NormalizeDouble() GBPUSD,M30: a = 1234567.90000100 Digits = 6


Мать...мать...мать... - ответило эхо!

 

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

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

 
ForexTools писал (а) >>

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

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


Только дилетанты и люди не знакомые с "железом" могут поверить в то, что плавающая арифметика это вещь приблизительная! Таким образом ленивые программисты разводят заказчиков-лохов.

Вы денечек погоняйте NormalizeDouble() с большими числами (к примеру можно с тем кодом который я привел), разберитесь в предмете вопроса, который я задал. И если сможете, то ответьте мне на мой вопрос. Буду Вам благодарен.

 

Попробую сформулировать свой Вопрос кратко и скорее всего он относится к разработчикам:



Функция NormalizeDouble() не работает с числами целая часть которых больше 9 разрядов. О причинах этого явления я догадываюсь.

Меня больше интересует будет ли это исправлено или это является ограничением и с этим надо научиться жить?

 
VBAG писал (а) >>

Только дилетанты и люди не знакомые с "железом" могут поверить в то, что плавающая арифметика это вещь приблизительная! Таким образом ленивые программисты разводят заказчиков-лохов.

Вы денечек погоняйте NormalizeDouble() с большими числами (к примеру можно с тем кодом который я привел), разберитесь в предмете вопроса, который я задал. И если сможете, то ответьте мне на мой вопрос. Буду Вам благодарен.


Только дилетанты будут утверждать, что плавающая арифметика - вещь точная. Ничего личного, но зачем так сразу ярлыки вешать?

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

точное_число = сумма_по_i(от -m до n) 2^i*Ai,

Ai = 0 или 1.

n - число целочисленных разрядов. Любое целое число легко представить конечной суммой степеней двоек. 

m - число разрядов для дробей. Тут гораздо сложнее - далеко не каждое вещественное число можно представить в виде конечной суммы степеней двоек. Например, число 0,4 является бесконечной суммой (вроде как, не помню точно). Не говоря уже об 1/3.

Примите это за должное, и все вопросы отпадут сами собой.


 
notused писал (а) >>

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

Есть такая книжечка древняя, ажно от 1988 года "Язык ассемблера для персонального компьютера фирмы IBM" Шнайдера. Там и про звон и про счисления очень доходчиво написано.

Советую почитать. Точность исчесления может задаваться. Скажем 28 знаков после запятой - это вещь приблизительная? Если мало можем еще добавить.


Спорить и обсуждать основы вычислительной техники желания нет!

Есть факт неработоспособности функции NormalizeDouble() с "большими" числами и нужен конкретный ответ на конкретно поставленный вопрос.

 
VBAG, чем вы там таким занимаетесь, что вам восемь знаков после запятой не хватает?
 

По поводу звона - вспомнил, преподаватель дискретной математики, по фамилии Булитко (эх, классный мужик, правда, после моего первого курса свалил в США преподавать), говорил. Правда, тогда он, в далёком уже, 2000 году, говорил, что частота процессора 1ГГц - это предел.  Лирика, в общем.

Ну и по поводу чисел.

Итак, всё зависит от кол-ва двоичных разрядов, выделямых для представления вещественной части. Пусть это число будет m. Тогда, погрешность представления не должно превышать (в абсолютных значениях): 2^(-m-1)

Если у Вас погрешность больше - покажите, я признаю ошибку (наводка - для большИх чисел, в целой части, используется больше битов, хотя общая размерность вещественного числа в битах - остаётся константой).

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

 
Integer писал (а) >>
VBAG, чем вы там таким занимаетесь, что вам восемь знаков после запятой не хватает?

Да ничего особенного. Просто была одна мыслишка тащить в одном дабле сразу два числа(можно добавить небольшой int в качестве указателя что-ли). Полезно иногда бывает.

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

 
Integer писал (а) >>
VBAG, чем вы там таким занимаетесь, что вам восемь знаков после запятой не хватает?

И еще до запятой не меньше семи. Короче, не менее 15 (!!!) значимых разрядов в мантиссе, если школу вспомнить. Навскидку на ум приходит только один вариант: нейросети. VBAG, ну правда интересно. Вот мне, например, при расчете машек вполне достаточно 5, от силы 6 значимых цифр.

P.S. Вот еще вариант: расчеты поправок при решении вековых уравнений или в ОТО. Но это уже явно не трейдинг...

P.P.S. А тащить двойную точность в одном дабле - вроде не очень сложная проблема. Всего-то и нужно написать библиотеку для такой двойной точности. Кстати, вот попробуй такую функцию из stdlib.mq4 (там вроде до 17):

string DoubleToStrMorePrecision(double number,int precision)
Причина обращения: