Особенности языка mql5, тонкости и приёмы работы - страница 158

 

Есть матрица, заполнена как большими, порядка 10e60, так и маленькими вроде 1e-40 значениями. И есть код такого плана

      for(k=-16;k<=16;++k)
      {
        double Tmp1=(double)(DoubleToString(Matrix[i][j],k));
        double Tmp2=(double)((string)Matrix[i][j]);
        if(Tmp1==Tmp2)
          break;
      }
Примерно в 27% случаев k=-15. В остальных случаях k=-16. Отсюда вопрос: как-то можно операцию (string)Matrix[i][j] заменить на более строгую функцию конвертации? Или может есть функция, которая отрезает часть знаков после запятой? NormalizeDouble не то, она 1.12345678e-40 обрежет в 0, а хотелось именно после запятой обрезать. Или конвертация в (string) живёт вообще своей жизнью и через функции не выражается? Спасибо.
 
traveller00:

Модуль разности.

 
fxsaber:

Модуль разности.

А можно немного поподробней? Может с примером кода? Разности между чем и чем?

Суть в том, что такая двойная конвертация (double)((string)Matrix[i][j]); обрежет неконтролируемое число символов после запятой. Хотелось бы с одной стороны сохранить это обрезание=уметь его повторять, а с другой это число символов контролировать.

 
traveller00:

А можно немного поподробней? Может с примером кода? Разности между чем и чем?

if (MathAbs(Value1 - Value2) < Epsilon)
 

А, я Вас понял. Нет, вопрос немного в другом. Сравнение тут скорее просто как пример, чтобы показать, что не получается заменить конвертацию через  (double)((string)Matrix[i][j]); на конвертацию через  DoubleToString. На самом деле стоит задача не сравнения. А скорее некоторого сброса точности через такую двойную конвертацию. И хотелось бы с одной стороны уметь повторять обрезание через  (string), а с другой контролировать точность обрезания как это делает  DoubleToString.

Ну и как побочный вопрос, неужто эти конвертации сделаны по-разному и живут своими отдельными и несвязанными жизнями.

 
traveller00:

А, я Вас понял. Нет, вопрос немного в другом. Сравнение тут скорее просто как пример, чтобы показать, что не получается заменить конвертацию через  (double)((string)Matrix[i][j]); на конвертацию через  DoubleToString. На самом деле стоит задача не сравнения. А скорее некоторого сброса точности через такую двойную конвертацию. И хотелось бы с одной стороны уметь повторять обрезание через  (string), а с другой контролировать точность обрезания как это делает  DoubleToString.

Ну и как побочный вопрос, неужто эти конвертации сделаны по-разному и живут своими отдельными и несвязанными жизнями.

Что-то непонятно, чем вас  NormalizeDouble  и DoubleToString  не удовлетворяют, в них любая точность какую хотите, или вы хотите чтобы точность была какая-то, но неизвестно какая?

 

Я согласен, что задача не совсем прозрачная. Потому что пытаюсь собрать некоторого рода костыль для тестов.

Скажем, есть число 1.0123456789e-50. Мне его нужно округлить с некоторой точностью, чтобы:

1. По дефолту оно работало как двойная конвертация через (string).

2. Точность при желании можно было контролировать.

Отсюда NormalizeDouble не подходит, она просто занулит это число. А  DoubleToString не позволяет повторить результат из п. 1.

Задача растёт из следующего вопроса. Как я писал выше, есть матрица. Вычисляется обратная к этой матрице. Иногда (возможно из-за погрешностей ввиду ограничения точности double) матрица получается вырожденная, и обратную к ней посчитать невозможно. Но если точность немного порезать, то обратную вычислить всё же получается. Вот и хотел прогнать тесты и набрать статистику, насколько получается вообще похожий на правду результат. Двойная конвертация через  (string) в большинстве случаев решает вопрос. Но иногда этого недостаточно и хотелось бы иметь возможность контролировать, на сколько резать точность. А  DoubleToString даже с перебором точности от -16 до 16 в большинстве случаев вопрос не решают.

 

Подскажите, pls.

В индикаторе порядок в сериях, напр. close[], устанавливается ArraySetAsSeries() один раз или как-то иначе ?

Это делается в OnCalculate() или можно в OnInit() ?

Столкнулся с непонятной ситуацией:

Порядок в  close[], установленный AS_SERIES при входе на первом тике, на следующем тике спонтанно меняется на обычный, т.е. !AS_SERIES.

Так и не нашел с чем это связано в коде.

 
Yurixx:

Подскажите, pls.

В индикаторе порядок в сериях, напр. close[], устанавливается ArraySetAsSeries() один раз или как-то иначе ?

Это делается в OnCalculate() или можно в OnInit() ?

Столкнулся с непонятной ситуацией:

Порядок в  close[], установленный AS_SERIES при входе на первом тике, на следующем тике спонтанно меняется на обычный, т.е. !AS_SERIES.

Так и не нашел с чем это связано в коде.

А в OnInit() вы не увидите массив close[]. И ни один из других предопределённых параметрами OnCalculate().

Отсюда вывод - только в OnCalculate().

 
Artyom Trishkin:

А в OnInit() вы не увидите массив close[]. И ни один из других предопределённых параметрами OnCalculate().

Отсюда вывод - только в OnCalculate().

Я пришел к такому же выводу. )))

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