Математическое округление. - страница 2

 
Quantum:

В Math.mqh есть перегрузка функции округления до заданного числа знаков после запятой.

#include <Math\Stat\Math.mqh>
void OnStart()
  {
//---
   Print(M_PI);
   for(int digits=0; digits<10; digits++)
     {
      Print(digits,": ",MathRound(M_PI,digits));
     }
  }
Это именно то что я искал. Про перегрузку вообще впервые слышу, почему этого в стандартном справочнике не указано? За подсказку огромнейшее спасибо!
 
A100:

А там только одно правило прописано? Вообще их несколько...

Округление к большему (округление к +∞, округление вверх, англ. ceiling — досл. «потолок») — если обнуляемые знаки не равны нулю, предшествующий знак увеличивают на единицу, если число положительное, или сохраняют, если число отрицательное.  

В школе не учились? Вообще не изучали такого в школе, никакого отбрасывания знаков, или увеличения до целого, только обычное округление - если последний знак меньше 5, то вниз, иначе вверх. 

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

---

Очень умиляет, периодическое возникновение столько серьезного обсуждения вопросов округления - 5 кл. ср. шк. 

 
h_bercut:
Это именно то что я искал. Про перегрузку вообще впервые слышу, почему этого в стандартном справочнике не указано? За подсказку огромнейшее спасибо!
А оно чем-то отличается от NormalizeDouble(). Только не подумав не отвечайте, пожалуйста.
 
Dmitry Fedoseev:

В школе не учились? Вообще не изучали такого в школе, никакого отбрасывания знаков, или увеличения до целого, только обычное округление - если последний знак меньше 5, то вниз, иначе вверх. 

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

---

Очень умиляет, периодическое возникновение столько серьезного обсуждения вопросов округления - 5 кл. ср. шк. 

Никогда не поздно ликвидировать пробелы в образовании. Со всеми правилами округления Вы прямо сейчас можете ознакомиться в статье Округление - Википедии.

Или в Excel впишите =ОКРУГЛВВЕРХ(161.4345;2) 

Только не ознакомившись - не отвечайте, пожалуйста.

 
Quantum:

В Math.mqh есть перегрузка функции округления до заданного числа знаков после запятой.

Крайне медленная реализация, к сожалению.
 
A100:

Никогда не поздно ликвидировать пробелы в образовании. Со всеми правилами округления Вы прямо сейчас можете ознакомиться в статье Округление - Википедии.

Или в Excel: =ОКРУГЛВВЕРХ(A2;2) 

Только не ознакомившись - не отвечайте, пожалуйста.

Боже мой))) Прям открытие Америки.

ОКРУГЛВВЕРХ() - перевод на русский язык имени функции  Ceil(). Хотя в экселе она называется ROUNDUP(), что бы у особо умных офисных работников не возникало сомнений...

 
fxsaber:
Крайне медленная реализация, к сожалению.
А какая быстрая? Та ваша что ли? Вам же Слава отвечал про ограниченность аргумента у нее.
 
Dmitry Fedoseev:
А оно чем-то отличается от NormalizeDouble(). Только не подумав не отвечайте, пожалуйста.

А там и думать нечего, достаточно немного переделать скрипт и убедиться, что результат один и тот же, когда округление до 8 знака, больше - начинаются различия:

#property strict
#include <Math\Stat\Math.mqh>
void OnStart()
  {
//---
   Print("Pi=",DoubleToString(M_PI,12));
   for(int digits=0; digits<10; digits++)
     {
      Print("MathRound to ",digits,": ",DoubleToString(MathRound(M_PI,digits),digits),"; "
       ,"NormalizeDouble to ",digits,": ",DoubleToString(NormalizeDouble(M_PI,digits),digits));
     }
  }
Pi=3.141592653590
MathRound to 0: 3; NormalizeDouble to 0: 3
MathRound to 1: 3.1; NormalizeDouble to 1: 3.1
MathRound to 2: 3.14; NormalizeDouble to 2: 3.14
MathRound to 3: 3.142; NormalizeDouble to 3: 3.142
MathRound to 4: 3.1416; NormalizeDouble to 4: 3.1416
MathRound to 5: 3.14159; NormalizeDouble to 5: 3.14159
MathRound to 6: 3.141593; NormalizeDouble to 6: 3.141593
MathRound to 7: 3.1415927; NormalizeDouble to 7: 3.1415927
MathRound to 8: 3.14159265; NormalizeDouble to 8: 3.14159265
MathRound to 9: 3.141592654; NormalizeDouble to 9: 3.141592650


 

 
h_bercut:

к сожалению оно округляет допустим 161.4345 до 161.43. Я думаю суть вы поймёте.

Нужно что бы 161.4345 округлилось до 161.44.  

Ещё один вариант:

//+------------------------------------------------------------------+
//|                                                     MathCeil.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property description "MathCeil: Возвращает ближайшее сверху целое числовое значение."
#property description "Задача: нужно из 161.4345 получить 161.44"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   double number=161.4345;
//--- умножаем число на 10 в степени 2, таким образом из 161.4345 получим 16143.45
   number*=MathPow(10,2);
//--- применим MathCeil: в итоге из 16143.45 получим 16144.0
   number=MathCeil(number);
//--- возвращаем количество разрядов в первоисходное состояние
   number/=MathPow(10,2);
  }
//+------------------------------------------------------------------+


Было 161.4345, стало 161.44

Файлы:
MathCeil.mq5  3 kb
 
Vladimir Karputov:

Ещё один вариант:


Было 161.4345, стало 161.44

Есть ещё вариант с MathFloor, тот больше подходит, а вот NormalizeDouble начинает чудить при разрядности числа больше 8:

#property strict
#include <Math\Stat\Math.mqh>
void OnStart()
  {
//---
   double pi=M_PI;
   Print("Pi=",DoubleToString(pi,16));
   for(int digits=0; digits<17; digits++)
     {
      double nor=0,rd=0,rdflo=0;
      rd=MathRound(pi,digits);
      nor=NormalizeDouble(pi,digits);
      rdflo=pi;
      rdflo*=MathPow(10,digits);
      rdflo=MathFloor(rdflo);
      rdflo/=MathPow(10,digits);
      Print("MathRound to ",digits,": ",DoubleToString(rd,digits),"; "
            ,"NormalizeDouble to ",digits,": ",DoubleToString(nor,digits),"; "
            ,"RoundFloor to ",digits,": ",DoubleToString(rdflo,digits));
     }
  }

Pi=3.1415926535897931
MathRound to 0: 3; NormalizeDouble to 0: 3; RoundFloor to 0: 3
MathRound to 1: 3.1; NormalizeDouble to 1: 3.1; RoundFloor to 1: 3.1
MathRound to 2: 3.14; NormalizeDouble to 2: 3.14; RoundFloor to 2: 3.14
MathRound to 3: 3.142; NormalizeDouble to 3: 3.142; RoundFloor to 3: 3.141
MathRound to 4: 3.1416; NormalizeDouble to 4: 3.1416; RoundFloor to 4: 3.1415
MathRound to 5: 3.14159; NormalizeDouble to 5: 3.14159; RoundFloor to 5: 3.14159
MathRound to 6: 3.141593; NormalizeDouble to 6: 3.141593; RoundFloor to 6: 3.141592
MathRound to 7: 3.1415927; NormalizeDouble to 7: 3.1415927; RoundFloor to 7: 3.1415926
MathRound to 8: 3.14159265; NormalizeDouble to 8: 3.14159265; RoundFloor to 8: 3.14159265
MathRound to 9: 3.141592654; NormalizeDouble to 9: 3.141592650; RoundFloor to 9: 3.141592653
MathRound to 10: 3.1415926536; NormalizeDouble to 10: 3.1415926500; RoundFloor to 10: 3.1415926535
MathRound to 11: 3.14159265359; NormalizeDouble to 11: 3.14159265000; RoundFloor to 11: 3.14159265358
MathRound to 12: 3.141592653590; NormalizeDouble to 12: 3.141592650000; RoundFloor to 12: 3.141592653589
MathRound to 13: 3.1415926535898; NormalizeDouble to 13: 3.1415926500000; RoundFloor to 13: 3.1415926535897
MathRound to 14: 3.14159265358979; NormalizeDouble to 14: 3.14159265000000; RoundFloor to 14: 3.14159265358979
MathRound to 15: 3.141592653589793; NormalizeDouble to 15: 3.141592650000000; RoundFloor to 15: 3.141592653589793
MathRound to 16: 3.1415926535897931; NormalizeDouble to 16: 3.1415926499999998; RoundFloor to 16: 3.1415926535897931