Округление чисел в МТ4 через NormalizeDouble - страница 3

 

Математика. 6 класс. Учебник. Никольский С.М., Потапов М.К. М.: 2012. - 256 с

Округление. 

Округление 

 

Какая бурная тема получилась. С округлением кажется МТ4 работает правильно.
Я имел виды, чтобы NormalizeDouble(0.055,2) не округлил число "0.055" до "0.06", а обрезал его до "0.05".

У меня непонятки с этими функциями МКЛ. Я не особо понимаю, зачем цены "1.0015223567" округлять функцией NormalizeDouble, если нужно лишь взять ОБРЕЗАННОЕ число до нужно знака.
То есть чтобы NormalizeDouble(1.001526789, 5) дало "1.00152" результат. Не нужно его до "
1.00153" округлять. Для этого должна быть функция RoundDouble =)

Такое возможно? Или нужно постоянно округлять и получать не те числа, которые хочешь? 

 

Вы бы уже определились, что ли. То округляет:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Округление чисел в МТ4 через NormalizeDouble

Roman Starinskij, 2016.01.21 10:03

Здравствуйте. Подскажите, в чем дело.

Почему функция NormalizeDouble(0.055,2) округляет число "0.055" до "0.06"?

Это же не функция огругления дробей.


то не округляет:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Округление чисел в МТ4 через NormalizeDouble

Roman Starinskij, 2016.01.25 14:30

Какая бурная тема получилась. С округлением кажется МТ4 работает правильно.
Я имел виды, чтобы NormalizeDouble(0.055,2) не округлил число "0.055" до "0.06", а обрезал его до "0.05".

У меня непонятки с этими функциями МКЛ. Я не особо понимаю, зачем цены "1.0015223567" округлять функцией NormalizeDouble, если нужно лишь взять ОБРЕЗАННОЕ число до нужно знака.
То есть чтобы NormalizeDouble(1.001526789, 5) дало "1.00152" результат. Не нужно его до "
1.00153" округлять. Для этого должна быть функция RoundDouble =)

Такое возможно? Или нужно постоянно округлять и получать не те числа, которые хочешь? 


Ну и для экспериментов:

//+------------------------------------------------------------------+
//|                                              NormalizeDouble.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs
#property description "Проверка NormalizeDouble"
input double   value=0.055;      // нормализуемое число 
input int      digits=2;         // кол-во знаков после запятой 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Print("Число ",value," округлённое с точностью до ",digits," знаков = ",NormalizeDouble(value,digits));
  }
//+------------------------------------------------------------------+
Файлы:
Test.mq5  2 kb
 
Roman Starinskij:

Какая бурная тема получилась. С округлением кажется МТ4 работает правильно.
Я имел виды, чтобы NormalizeDouble(0.055,2) не округлил число "0.055" до "0.06", а обрезал его до "0.05".

У меня непонятки с этими функциями МКЛ. Я не особо понимаю, зачем цены "1.0015223567" округлять функцией NormalizeDouble, если нужно лишь взять ОБРЕЗАННОЕ число до нужно знака.
То есть чтобы NormalizeDouble(1.001526789, 5) дало "1.00152" результат. Не нужно его до "
1.00153" округлять. Для этого должна быть функция RoundDouble =)

Такое возможно? Или нужно постоянно округлять и получать не те числа, которые хочешь? 

Если надо обрезать - обрезайте,  если надо округлять - округляйте. Функция NormalkizeDouble() округляет и это именно то, что надо чаще всего. 

С чего взяли, что для округления должно быть RoundDouble(), а не NormalizeDouble(). Вы что ли этот мир создавали? А ничего, что шар катается, а у квадрата четыре угла?   

 
Roman Starinskij:

Какая бурная тема получилась.


Всё от того, что топикстартер не читает документацию по языку и не слушает, что ему говорят
 
Slawa:
Всё от того, что топикстартер не читает документацию по языку и не слушает, что ему говорят

Немного не понятно следующее поведение деление и округление дробей.

Есть 2 уравнения:
0.06-0.02 = 0.03999999999999999
0.06-0.024 = 0.036

Воспользовавшись рекомендованной функцией NormalizeDouble мы получим такие результаты:
0.03999999999999999 = 0.04
0.036 = 0.04

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

 
Roman Starinskij:

Немного не понятно следующее поведение деление и округление дробей.

Есть 2 уравнения:
0.06-0.02 = 0.03999999999999999
0.06-0.024 = 0.036

Воспользовавшись рекомендованной функцией NormalizeDouble мы получим такие результаты:
0.03999999999999999 = 0.04
0.036 = 0.04

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

Ваш обычный калькулятор считает не правильно, должно быть так:

 

 
Slawa:
Всё от того, что топикстартер не читает документацию по языку и не слушает, что ему говорят

если N+1 знак < 5, то N-ый знак сохраняют, а N+1 и все последующие обнуляют;

если N+1 знак ≥ 5, то N-ый знак увеличивают на единицу, а N+1 и все последующие обнуляют; 

 

Извиняюсь но так и не поняла, почему округляя на '2' сразу не возможно получить = 0.06000000

void OnStart()
  {

   double v1 = NormalizeDouble(0.055,3);
   double v2 = NormalizeDouble(0.0549,3);

   v1=NormalizeDouble(v1,2);
   v2=NormalizeDouble(v2,2);
   Print("v1 = ",DoubleToString(v1),", v2 = ",DoubleToString(v2));

  }

v1 = 0.06000000, v2 = 0.06000000

void OnStart()
  {

   double v1 = NormalizeDouble(0.055,2);
   double v2 = NormalizeDouble(0.0549,2);

   Print("v1 = ",DoubleToString(v1),", v2 = ",DoubleToString(v2));

  }

v1 = 0.06000000, v2 = 0.05000000

void OnStart()
  {
   for(int i=7;i>=1;i--)
     {
      double v1 = 1.1234567;
      double v2 = NormalizeDouble(v1,i+1);

      v1=NormalizeDouble(v1,i);
      v2=NormalizeDouble(v2,i);
      Print("v1 = ",i," = ",DoubleToString(v1,7),", v2 = ",i," = ",DoubleToString(v2,7));
     }
     Print("---");
  }

---

v1 = 1 = 1.1000000, v2 = 1 = 1.1000000
v1 = 2 = 1.1200000, v2 = 2 = 1.1200000
v1 = 3 = 1.1230000, v2 = 3 = 1.1240000
v1 = 4 = 1.1235000, v2 = 4 = 1.1235000
v1 = 5 = 1.1234600, v2 = 5 = 1.1234600
v1 = 6 = 1.1234570, v2 = 6 = 1.1234570
v1 = 7 = 1.1234567, v2 = 7 = 1.1234567




 
lilita bogachkova:


Извиняюсь но так и не поняла, почему округляя на '2' сразу не возможно получить = 0.06000000


Потому-что равно 0.6, поэтому 0.5 получается только путем мухлежа. 
 
lilita bogachkova:

Извиняюсь но так и не поняла, почему округляя на '2' сразу не возможно получить = 0.06000000


Когда нормализуется только один знак, то там все просто: 0, 1, 2, 3, 4 -> 0, а 5, 6, 7, 8, 9 -> 1

Если нормализуется два знака, то в расчет принимаются двузначные числа: 0 - 49 -> 0, а 50 - 99 -> 1. Ведь если число 1.49 нужно округлить до целых, то неужели должны получить 2, до которого 51-а сотая против имеющихся 49-и сотых расстояния до 1? 

Тоже самое с трехзначными, четырехзначными и т. д.

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