标准功能/方法的其他实现方式 - 页 12

 
Nikolai Semko:

哇--太酷了!谢谢。我想--每次都算数。是的,这很合乎逻辑,你已经可以在编译时计算出来了。
所以,像这样。

但写成DBL_MANT_DIG 而不是53会更正确。

如果双数的所有值都是小数,则收益最小的情况。

1.你的实现是不完整的,只有在事先知道可能的值的范围时才能使用。

以下是完整实现的代码

union Double
  {    
   double x;
   ulong  ul;
  };

double Ceil (double x)
  {
   Double dbl;   
   dbl.x=x;   
//--- убираем знак
   ulong uv=dbl.ul & 0x7fffffffffffffff;
//--- значение меньше единицы
   if(uv<0x3FF0000000000000)
     {
      //--- ноль возвращаем как есть
      if(!uv)
         return(x);
      //--- оставим только знак
      dbl.ul &= 0x8000000000000000;
      //--- положительные округляем до 1.0
      if(!dbl.ul)
         return(1.0);
      //--- отрицательные округляем до -0.0
      return(dbl.x);
     }
//--- полностью целое число
   if(uv>=0x4340000000000000)
      return(x);
//--- получим знак
   ulong sign=dbl.ul&0x8000000000000000;     
//--- IEEE магия (для домашнего изучения)
   ulong nuv=uv & ~(((ulong)1<<(51-char(uv>>52)))-1);
//--- для положительного значения
   if(!sign)
     {          
      dbl.ul=nuv;
      //--- добавим единицу, если число не целое
      if(nuv!=uv)      
         dbl.x+=1.0;
     }
   else
     {
      //--- для отрицательного просто добавим знак
      dbl.ul=nuv|sign;
     }
//---   
   return(dbl.x);
  }
2018.08.27 16:11:15.014    TestRound (EURUSD,H1)    Время выполнения ceil =  6.382 наносекунд, Контрольная сумма = 507104
2018.08.27 16:11:15.028    TestRound (EURUSD,H1)    Время выполнения Ceil =  4.792 наносекунд, Контрольная сумма = 507104


2.当优化功能被禁用时,为调试而编译的自写函数明显比内置函数慢。

 
Ilyas:

1.你的实现是不完整的,只有在事先知道可能的值的范围时才能使用。

以下是完整实现的代码

2.当优化功能被禁用时,自写函数在编译调试时要比内置函数慢得多。

非常感谢你,伊利亚斯,感谢你的优秀代码。

当然,它在这里是一个很好的帮手。

我正在研究它。

ZS这个 版本不是完全一样吗?
 
Nikolai Semko:


尼古拉,你好。我看到你在做图形工作,但我不完全了解实际的任务是什么。你在做什么工作?

加快渲染功能的速度?

 
我想推测的主题是:你不能用你的头脑理解俄罗斯,但后来我把注意力转向了主题:标准函数/方法的替代实现。
 

总的来说,关于这个主题,我已经成功实现了在画布上绘画的完全替代方法。不使用CCanvas类

也就是说,不是修改一套单独的功能,而是创建一个完整的绘图机制,由一个单一的块组成。

(当然,我很难在代码中证明这一切,因为有很多代码,而且是以非标准的方式写的,但我想告诉你的是,一般情况下)。

所以。

1.区块(功能)。

void Нарисовать_элемент(int Канвас, int Элемент = 0) 

只接受2个参数 - Kanvas和Element。

  • Kanvas 是一个MT-对象。
  • 元素 是一种图画。

2.每个MT-对象都有自己的资源分配给它。它被立即使用ResourceReadImage()加载到 "像素数组 "中;如果资源还不存在,就会设置一个标志,这将随后确定周期在内核上的范围。

3.内核,是一个所有元素的属性数组。它包含物体的尺寸数据,以及不同状态的颜色。还有很多其他的数据。每个对象总共有235个属性。同时,每个元素(取决于类型)可以包含1到11个对象(没有限制)。

4.在绘图块中,每个对象都意味着绘图的一个 "细节"。因此,在内核中按对象进行的循环,是一个绘制循环,在这个循环中,每个Detail的图像被创建。如果一个画布尚未创建,则仅对该画布的所有细节进行一个完整的循环。在内核中对每个细节规定了对Kanvas的归属。也就是说,所有的Kanvases,(和零件)都有自己的序列号。通过这些数字,有可能只画出所需的Kanvas的内容。

4.如果一个Kanvas已经存在,并且它的图像是以像素数组的形式加载的,而我们只需要重绘一个元素(例如在一个颜色变化事件中),那么核心循环的范围就会缩小到单一元素的边界,而这个元素的编号是由绘图函数获得的。


这幅画本身很简单。它是在一维数组的单元格中从左到右的一个循环。在周期设定之前。

1.起始单元(A点)。

2.终端细胞(B点)。

3.走过去。

很难用一句话概括1500行代码块的操作。这是一个功能,已经成长和打磨了20个月。我几乎对它了如指掌,这使我很容易继续发展它。

通过使用内核和焦点(将重要的变量放在全局范围内),该块获得了巨大的可能性。他们的极限至今我还看不出来。

因此,这就是标准的坎布画法的替代方案。


zy。如果对细节感兴趣,我可以解释。

 

这是块的开头的样子:

 //+------------------------------------------------------------------+
//|                                                     Анимация.mqh |
//|                                                      Peter Konow |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
//--------------------------------------------------------------------
#include<CONNECTION.mqh>
//--------------------------------------------------------------------

//--------------------------------------------------
void Нарисовать_элемент( int Канвас, int Элемент = 0 )
{
 int _Цвет_,_Поправка, Указание = Элемент; 
   int        Цвет_текста,Размер_шрифта,Стиль_шрифта, Длинна_этого_текста, X_Координата_текста,Отступ_X,Отступ_Y;
   string     Текст, Шрифт; 
 //----------------------------------------
 //----------------------------------------  
 int Эта_деталь,Номер_пикселя_элемента,Угол_наклона_детали, Цвет_детали,Ячейка_состояния,Последняя_деталь, 
     Индекс_лейбла,Исходный_элемент,Этот_X,Этот_Y,Низ,Право,Цвет_пикселя,Alfa,Массив_пикселей[],
     Метод_расчета_цвета,Градиент_поверхности,Всех_полос_градиента,Шаг_градиента,Градиент_этого_состояния,Шаг_градиента_этого_состояния;
 //----------------------------------------
 int Окно = G_CORE[Канвас][_W_NUMBER];
 int MAIN_FRAME          =   Окно + 1 ; 
 int Последний_объект    = G_CORE[Окно][_LAST_OBJECT];
 //----------------------------------------
   if (Элемент != REDROW_WHOLE_CANVAS && Элемент != REDROW_CHANGED_ELEMENTS)Исходный_элемент = Элемент;
   else 
    {
     Исходный_элемент = G_CORE[Окно][_FIRST_OBJECT];
    }    
 //-----------------------------------------------------------------
 int X_Исходного_элемента       =  G_CORE[Исходный_элемент][_X]; 
 int Y_Исходного_элемента       =  G_CORE[Исходный_элемент][_Y]; 
 int X_SIZE_исходного_элемента  =  G_CORE[Исходный_элемент][_X_SIZE]; 
 int Y_SIZE_исходного_элемента  =  G_CORE[Исходный_элемент][_Y_SIZE]; 
 int Низ_исходного_элемента     =  Y_Исходного_элемента + Y_SIZE_исходного_элемента;
 int Право_исходного_элемента   =  X_Исходного_элемента + X_SIZE_исходного_элемента;
 //----------------------------------------------------------------
   int hight, width, Ресурс_существует;
   int GAC, Событие_изменения_GAC; 
   //-----------------------------------
  GAC                     = G_CORE[Канвас][_GLOBAL_ALFA_CORRECTION];
  Событие_изменения_GAC   = G_CORE[Канвас][_GLOBAL_ALFA_CHANGED];
   //-----------------------------------
 //-------------------------------------------------- 
 //Определяем метод расчета цвета. Если глобальная Alfa != 0,
 //то расчитываем по методу COLOR_FORMAT_ARGB_NORMALIZE (медленный метод),
 //если глобальная Alfa == 0, то расчитываем по методу COLOR_FORMAT_ARGB_RAW.
 //----- || G_CORE[Канвас][_CUSTOM_BACKGROUND_TRANSPERANCY]---------------------------------------------
 if (GAC)Метод_расчета_цвета = COLOR_FORMAT_ARGB_NORMALIZE ;
 else    Метод_расчета_цвета = COLOR_FORMAT_ARGB_RAW ;
 //Alert("*",__FUNCTION__,"*"," Метод_расчета_цвета  ",Метод_расчета_цвета);
 //--------------------------------------------------     
  
  Имя_ресурса = "::" + ( string )G_CORE[Канвас][_NAME];
  Ресурс_существует = ResourceReadImage (Имя_ресурса,Массив_пикселей,width,hight);
   //-----------------------------------
  Последняя_деталь = G_CORE[Окно][_LAST_OBJECT];
   //-----------------------------------
   if (Ресурс_существует)
    {
     if (!Элемент)Элемент = ЭЛЕМЕНТ;
     Эта_деталь = Элемент; 
    } 
 //------------------------------------  
   if (
        ( Ресурс_существует 
     && (
            Событие_изменения_GAC 
         || Событие_развертки 
         || Переименование_файла 
         || Переименование_папки 
         || Изменение_ширины_столбца
         || Явление_столбцов
         || Ротация_колонок
         || (Элемент == REDROW_WHOLE_CANVAS)
        ))
      || !Ресурс_существует  
      ||  !G_CORE[Окно][_WINDOW_WAS_OPENED]
      ||  !G_CORE[Канвас][_RESOURCE_CREATED]
    )
    {
     if (Ресурс_существует)Ресурс_существует = 0 ;
     ArrayResize (Массив_пикселей,G_CORE[Канвас][_Y_SIZE] * G_CORE[Канвас][_X_SIZE]);
     Эта_деталь = MAIN_FRAME; //Канвас - 1; 
     //-----------------------------   
     if (Событие_изменения_GAC)G_CORE[Канвас][_GLOBAL_ALFA_CHANGED] = 0 ;     
    }
 //-------------------------------------
 if (Событие_динамичного_окна)
   {
    Эта_деталь = Канвас;
    Последняя_деталь = Канвас  + 18 ;
   } 
 //-------------------------------------
 if (Указание == REDROW_CHANGED_ELEMENTS)
   {
    Эта_деталь       = 6561 ; //Канвас;
    Последняя_деталь = obj_limit; //G_CORE[G_CORE[Канвас][_W_NUMBER]][_LAST_OBJECT];////
   } 
 //-------------------------------------
 //-------------------------------------
//==================================================================================================================================================================================================== 
//==================================================================================================================================================================================================== 
//==================================================================================================================================================================================================== 
//==================================================================================================================================================================================================== 
//==================================================================================================================================================================================================== 
 for ( int Деталь = Эта_деталь; Деталь <= Последняя_деталь; Деталь++)
   {
     if (!G_CORE[Деталь][_NAME]){ break ;} 
     //-------------------------------------------------------------
     //На событиях интерактивности, если ресурс канваса уже был создан, мы меняем только
     //одну деталь на этом канвасе и выходим из цикла.
     //-------------------------------------------------------------
     int     _Элемент                    =   G_CORE[Деталь][_MAIN]; 
     int     Головной_элемент_группы     =   G_CORE[_Элемент][_GROUP_HEAD_OBJECT];
     string Его_имя                     =   CONTENT[G_CORE[_Элемент][_N_TEXT]];
     int     Деталь_спрятана             =   G_CORE[Деталь][_HIDE];
     //-------------------------------------------------------------
     int Поставлен_в_очередь_на_перерисовку = G_CORE[_Элемент][_REDROW];
     //-------------------------------------------------------------
     int     Элемент_синхронизирован     =   G_CORE[_Элемент][_SYNC];
     int     Канвас_детали               =   G_CORE[Деталь][_CANVAS];
     int     Категория_канваса           =   G_CORE[Канвас_детали][_CATEGORY];
     int     Тип_объекта_детали          =   G_CORE[Деталь][_OBJ_TYPE];
     int     Группа_элемента_детали      =   G_CORE[_Элемент][_GROUP]; 
     int     Элемент_таблицы             =   G_CORE[_Элемент][_TABLE];    
   // if(Событие_динамичного_окна)Alert("Канвас  ",Канвас,"  Эта_деталь  ",Эта_деталь,"  Деталь   ",Деталь,"   Канвас_детали  ",Канвас_детали); //&& Группа_элемента_детали != FIELD
     //--------------------------------------
     int     X_Элемента_этой_детали      =   G_CORE[_Элемент][_X]; 
     int     Y_Элемента_этой_детали      =   G_CORE[_Элемент][_Y]; 
     int     X_SIZE_Элемента_этой_детали =   G_CORE[_Элемент][_X_SIZE]; 
     int     Y_SIZE_Элемента_этой_детали =   G_CORE[_Элемент][_Y_SIZE]; 
     int     Низ_этого_элемента          =   Y_Элемента_этой_детали +  Y_SIZE_Элемента_этой_детали; 
     int     Право_этого_элемента        =   X_Элемента_этой_детали +  X_SIZE_Элемента_этой_детали;     
     //--------------------------------------
     int Деталь_спрятана_функцией       =   G_CORE[Деталь][_HIDDEN_BY_FUNCTION]; 
     int Эта_деталь_спрятана                =   G_CORE[Деталь][_IS_HIDDEN];
     int Элемент_спрятан                    =   G_CORE[_Элемент][_IS_HIDDEN];
     int Элемент_спрятан_функцией       =   G_CORE[_Элемент][_HIDDEN_BY_FUNCTION]; 
     int Головной_элемент_группы_спрятан_функцией = G_CORE[Головной_элемент_группы][_HIDDEN_BY_FUNCTION];   
     //-------------------------------------- 
     int Контроллер_явления             =   G_CORE[_Элемент][_APPEARANCE_ID]; 
     int Управляемость_явлением         =   Контроллер_явления;
     //--------------------------------------
     if (Управляемость_явлением)
      {
       int Состояние_контролирующего_элемента = G_CORE[Контроллер_явления][_CURRENT_STATE];
      } 
     //--------------------------------------          
     int     X_этой_детали               =   G_CORE[Деталь][_X]; 
     int     Y_этой_детали               =   G_CORE[Деталь][_Y]; 
     int     X_SIZE_этой_детали          =   G_CORE[Деталь][_X_SIZE]; 
     int     Y_SIZE_этой_детали          =   G_CORE[Деталь][_Y_SIZE]; 
     int     Низ_этой_детали             =   Y_этой_детали +  Y_SIZE_этой_детали; 
     int     Право_этой_детали           =   X_этой_детали +  X_SIZE_этой_детали; 
     //-------------------------------------------------------------
     int   Элемент_под_курсором          =   G_CORE[_Элемент][_ELEMENT_POINTED];     
     //-------------------------------------------------------------
     if (Группа_элемента_детали != I)
      {
       Этот_X = X_Элемента_этой_детали;
       Этот_Y = Y_Элемента_этой_детали;
       Низ    = Низ_этого_элемента;
       Право  = Право_этого_элемента;
      }
     else
      {
       Этот_X = X_этой_детали;
       Этот_Y = Y_этой_детали;
       Низ    = Низ_этой_детали;
       Право  = Право_этой_детали;
      }  
     //-------------------------------------------------------------
       int     Тип_привязки_детали_по_оси_X        =   G_CORE[Деталь][_A1]; 
       int     Позиция_текста_на_элемента          =   G_CORE[Деталь][_TEXT_POSITION];                      
       int     Тип_детали                          =   G_CORE[Деталь][_BITMAP_TYPE];
       int     Категория_детали                    =   G_CORE[Деталь][_CATEGORY];
       int     Подкатегория_детали                 =   G_CORE[Деталь][_SUBCATEGORY];
       int     Номер_состовного_элемента           =   G_CORE[Деталь][_SUB_ELEMENT];
     //-------------------------------------------------------------    
     if (
            (
                !Деталь_спрятана_функцией 
             && !Элемент_спрятан_функцией 
             && !Головной_элемент_группы_спрятан_функцией 
             && !Эта_деталь_спрятана
             && !Элемент_спрятан
            )
        && !(Управляемость_явлением && Состояние_контролирующего_элемента != _ACTIVATED_STATE && Состояние_контролирующего_элемента != _ACTIVATED_HIGHLIGHTED && Состояние_контролирующего_элемента != _ACTIVATED_BLOCKED)
        &&((
               Ресурс_существует 
           && (   //рисуем детали только этого элемента
                  _Элемент == Элемент
                   //Рисуем все детали канваса на событии изменения ширины столбца таблицы. 
               || Изменение_ширины_столбца
               || Явление_столбцов
               || Ротация_колонок
               //Этот элемент синхронизирован с исходным элементом.
               // || Элемент_синхронизирован == Исходный_элемент
                   //или элементов которые находятся на площади этого элемента и должны быть перерисованы, чтобы не быть загороженными.
              || ( 
                      ((Этот_X <= X_Исходного_элемента && Право_этого_элемента > X_Исходного_элемента
                    &&  Этот_Y <= Низ_исходного_элемента && Низ_этого_элемента >= Y_Исходного_элемента)  
                                        
                    ||(Этот_X >= X_Исходного_элемента && Этот_X <= Право_исходного_элемента
                    && Этот_Y >= Y_Исходного_элемента && Этот_Y <= Низ_исходного_элемента))
                    && !Элемент_таблицы     
                  ) 
               || (G_CORE[_Элемент][_REDROW] && ((Событие_открытия_окна && !Событие_обновления_окна) || (Указание == REDROW_CHANGED_ELEMENTS && Канвас_детали == Канвас)))   
              ) //только  этого канваса и только НЕ сам канвас как деталь.  && Группа_детали_исходного_элемента != TEXT
           && (Канвас_детали == Канвас && ((Деталь != Канвас || (Событие_динамичного_окна && Деталь != Канвас + 2 )) || Перерисовка_окна_в_фокусе))
          )
       //Если ресурс не существует, то рисуем все детали этого канваса.   
       || (!Ресурс_существует && Канвас_детали == Канвас)) 
      )    
     { //if(!Ресурс_существует && Канвас_детали == Канвас)if(Событие_Drag_n_Drop)
       //Alert("*",__FUNCTION__,"*","  Имя элемента  ",Его_имя,"  Эта_деталь  ",Деталь,"    Деталь_спрятана  ",Деталь_спрятана,"  X_Элемента_этой_детали  ",X_Элемента_этой_детали,"  Y_Элемента_этой_детали  ",Y_Элемента_этой_детали);//if(СОБЫТИЕ_ИНТЕРФЕЙСА == _SCROLLER_EVENT || СОБЫТИЕ_ИНТЕРФЕЙСА == _OBJECT_POINTED)Alert("*",__FUNCTION__,"*","   Окно  ",Окно,"  Канвас  ",Канвас," _MAIN ",G_CORE[Деталь][_MAIN],"  Деталь  ",Деталь,"   Группа элемента   ",G_CORE[Деталь][_GROUP]);
       //---------------------------------------
       //if(Перерисовка_окна_в_фокусе && Категория_канваса == _OCWC)Alert(__FUNCTION__,"  Перерисовка_окна_в_фокусе, Категория_канваса == _OCWC");
       //---------------------------------------
       //Снимаем флаг очереди на перерисовку после прохождения условия.
       //---------------------------------------
       if (Поставлен_в_очередь_на_перерисовку && Деталь == _Элемент + G_CORE[_Элемент][_ALL_OBJECTS_IN_ELEMENT] - 1 )
        {
         G_CORE[_Элемент][_REDROW] = 0 ;
        } 
       //---------------------------------------
     // int Пиксель_канваса_детали      =  G_CORE[Канвас_детали][_PIXEL_INDEX];
       int Состояние_канваса_детали    =  G_CORE[Канвас_детали][_CURRENT_STATE];
       int Ячейка_состояния_канваса    =  G_CORE[Канвас_детали][_NEUTRAL_STATE];
       //-------------------------------------
     // int Цвет_пикселя_канваса_детали =  STANDART_GROUPS[Ячейка_состояния_канваса + 3 + Пиксель_канваса_детали*2];
       //---------------------------------------
       int     Состояние_элемента                  =   G_CORE[_Элемент][_CURRENT_STATE];
       //---------------------------------------
       if (!Состояние_элемента)
        {
         Состояние_элемента = _NEUTRAL_STATE;
         G_CORE[_Элемент][_CURRENT_STATE] = _NEUTRAL_STATE;
        }
       //--------------------------------------  
       int     Состояние_детали                    =   G_CORE[Деталь][_CURRENT_STATE];
       //--------------------------------------- 
       if (Состояние_детали != Состояние_элемента)
        {
         Состояние_детали = Состояние_элемента;
         G_CORE[Деталь][_CURRENT_STATE] =  Состояние_элемента;
        } 
       //Alert("Нарисовать_элемент()  _Элемент  ",_Элемент,"  Деталь  ",Деталь, "   Группа элемента   ",G_CORE[_Элемент][_GROUP]," Cостояние элемента  ",G_CORE[_Элемент][_CURRENT_STATE]," Состояние_детали  ",G_CORE[Деталь][_CURRENT_STATE]);   
       //---------------------------------------
       int     Состояние_составного_элемента       =   G_CORE[Номер_состовного_элемента][_SUB_ELEMENT_CURRENT_STATE];
       //---------------------------------------
       //Условие if(!Состояние_составного_элемента) создавало баг - было переопределение состояния главого элемента детали.
       //---------------------------------------
       if (!Состояние_составного_элемента && Номер_состовного_элемента != _Элемент)
        {
         Состояние_составного_элемента  =   _NEUTRAL_STATE;
         G_CORE[Номер_состовного_элемента][_CURRENT_STATE] = _NEUTRAL_STATE;
        }  
       //---------------------------------------  
       //Определяем текущее состояние детали по состоянию составного элемента, которому она принадлежит. 
       //(При этом, составной элемент может быть главным элементом).
       //---------------------------------------    
       if (G_CORE[Деталь][_SUB_ELEMENT] == _Элемент)
        {
         Состояние_детали = Состояние_элемента;
         // Alert("_SUB_ELEMENT   ",G_CORE[Деталь][_SUB_ELEMENT],"   Состояние_элемента   ",Состояние_элемента,"  Состояние_составного_элемента  ",Состояние_составного_элемента,"  Состояние_детали ",Состояние_детали); 
        } 
       //---------------------------------------
       //При этом, если деталь принадлежит составному элементу, то ее состояние совпадаем с состоянием составного элемента,
       //которое прописано в другом параметре, - не _CURRENT_STATE, а _SUB_ELEMENT_CURRENT_STATE. Это значит,
       //что если деталь принадлежит главному элемету, ее состояние будет братся из параметра _CURRENT_STATE главного элемета,
       //а если принадлежит составному, - то из параметра _SUB_ELEMENT_CURRENT_STATE составного элемета.
       //Поэтому добавлено условие: " && Номер_состовного_элемента != _Элемент".
       //---------------------------------------
       if (G_CORE[Деталь][_SUB_ELEMENT] == Номер_состовного_элемента && Номер_состовного_элемента != _Элемент)
        {
         Состояние_детали = Состояние_составного_элемента;
        } 
       //---------------------------------------
   
       //---------------------------------------
       int Группа_составного_элемента             =   G_CORE[Номер_состовного_элемента][_SUB_ELEMENT_GROUP];
       //---------------------------------------
       int Высота_элемента                        =   G_CORE[_Элемент][_Y_SIZE];  
       int Ширина_элемента                        =   G_CORE[_Элемент][_X_SIZE];     
       //--------------------------------------- 
       int X_детали                               =   G_CORE[Деталь][_X];
       int Y_детали                               =   G_CORE[Деталь][_Y];
       //-----------------------
       if (!G_CORE[Деталь][_SUB_ELEMENT_CURRENT_STATE])G_CORE[Деталь][_SUB_ELEMENT_CURRENT_STATE] = _NEUTRAL_STATE;
       //-----------------------
       int Объект_A2G                             =   G_CORE[Деталь][_ADAPT_2_GRADIENT];
       //--------------------------------
       int Тип_сценария                           =   G_CORE[Деталь][_CURRENT_SCENARIO_TYPE];
       int Номер_сценария                         =   SI_PROPERTIES[G_CORE[Деталь][_SI_PROPERTIES]][Тип_сценария];  
       int Эта_сцена                              =   G_CORE[Деталь][_CURRENT_SCENE]; 
       int Значение_по_сценарию                   =   SCENARIOS[Номер_сценария][Эта_сцена];         
       //--------------------------------
       int X_полотна                              =   G_CORE[Канвас][_X];
       int Y_полотна                              =   G_CORE[Канвас][_Y]; 
       //--------------------------------
       //--------------------------------
       int Отступ_детали_X                        =   X_детали - G_CORE[Канвас][_X];
       int Отступ_детали_Y                        =   Y_детали - G_CORE[Канвас][_Y];
       //--------------------------------
       int Высота_детали                          =   G_CORE[Деталь][_Y_SIZE];
       int Длинна_детали                          =   G_CORE[Деталь][_X_SIZE];
       //-----------------------
       int Ширина_полотна                         =   G_CORE[Канвас][_X_SIZE];
       int Высота_полотна                         =   G_CORE[Канвас][_Y_SIZE]; 
       //-----------------------
       int Правая_граница_детали                  =   X_детали  + Длинна_детали;
       int Правая_граница_полотна                 =   X_полотна + G_CORE[Канвас][_X_SIZE];      
       //-----------------------
      _Поправка = 0 ;
       //-----------------------
       if (Подкатегория_детали == _DINAMIC_PLATFORM)
        {
         _Поправка = 30 ;
         Длинна_детали                           =   G_CORE[Канвас][_VISIBLE_X_SIZE] + _Поправка;
         Высота_детали                           =   G_CORE[Канвас][_VISIBLE_Y_SIZE] + _Поправка;
         Правая_граница_детали                   =   X_детали  + Длинна_детали;
         Правая_граница_полотна                  =   X_полотна + Длинна_детали;    
         //-------------------------------------
       
        }    
       //--------------------------------
 
Ilyas:

1.你的实现是不完整的,只有在事先知道可能的值的范围时才能使用。

以下是完整实现的代码

再次感谢您提供的代码。我一直在思索这些位面的问题,就像双重的。事实证明,这并不像我之前想象的那么容易。
我根据你的版本 稍作调整。只有一个区别:你的版本在值-1>x>0时返回Ceil(-0.1)= - 0.0,而我的版本返回0.0。虽然我不知道它什么时候可能会有用。

而你得到的是以下结果。

//double Ceil(double x) { return double((x!=x || x>(long)1<<53 || x<-(long)1<<53)?x:(x-(long)x>0)?(long)x+1:(long)x);}
  double Ceil(double x) { return double((x!=x || x>(long)1<<53 || x<-(long)1<<53)?x:(x-(long)x>0)?(long)x+1:(x>-1 && x<0)?-0.0:(long)x);}

同样的事情,只是可读性和评论。

double Ceil(double x)
  {
   if(x!=x ||            // если x = NaN(SNaN) т.е. переполнение или ошибка
      x> (long)1<<53 ||  // или число x положительное и превышает максимальную возможную мантиссу, т.е. дробная часть в x точно отсутствует 
      x<-(long)1<<53)    // или число x отрицательное и превышает максимальную возможную мантиссу, т.е. дробная часть в x точно отсутствует 
      return(x);
   if(x-(long)x>0)       // Если число положительное или дробная часть не равна нулю
      return(long)x+1.0; // добавляем к бездробной части 1
   else if(x>-1 && x<0)  // Если -1 < x < 0
   return -0.0;          // то возвращаем -0.0
   else return (double)long(x);
  }

我写了一个脚本(附后),它证实了与你的版本100%一致。
但这个变体更快、更紧凑,而且在我看来,更具有可读性。

请注意,在函数主体中甚至没有创建一个变量,而你的版本创建了4个8字节的变量。
也许我错了?

当输入的x总是有一个小数部分时的结果。

2018.08.27 18:42:37.616 TestCeil (EURUSD,M1)    Время выполнения функции CeilI =  1.321 наносекунд, Контрольная сумма = 5250492895.0
2018.08.27 18:42:37.619 TestCeil (EURUSD,M1)    Время выполнения функции CeilN =  1.094 наносекунд, Контрольная сумма = 5250492895.0
2018.08.27 18:42:37.623 TestCeil (EURUSD,M1)    Время выполнения функции ceil =  2.962 наносекунд, Контрольная сумма = 5250492895.0
2018.08.27 18:42:37.623 TestCeil (EURUSD,M1)    Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

当输入的x有一个分数部分时,结果是罕见的。

2018.08.27 18:49:45.734 TestCeil (EURUSD,M1)    Время выполнения функции CeilI =  0.307 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.27 18:49:45.736 TestCeil (EURUSD,M1)    Время выполнения функции CeilN =  0.102 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.27 18:49:45.738 TestCeil (EURUSD,M1)    Время выполнения функции ceil =  1.026 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.27 18:49:45.738 TestCeil (EURUSD,M1)    Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать
伊利亚斯


2.当优化功能被禁用时,自写的函数在编译调试时明显比内置函数慢。

目前还不清楚为什么在调试时需要这种速度。
但如果你真的需要它,你可以使用该结构。

#ifdef _DEBUG x=Ceil(y);
#else  x=ceil(y); #endif 


还有一件事我不明白。

为什么文件和实际的DBL_MANT_DIG= 53?

因为根据同一维基百科=52。
而且,就像,从你的代码 中可以看出,52也?

附加的文件:
TestCeil.mq5  15 kb
 
Реter Konow:

尼古拉,你好。我看到你在做图形工作,但我不完全了解实际的任务是什么。你在做什么工作?

加快渲染功能的速度?

你好,Piotr!
我将当面答复。

 
 
Nikolai Semko:
还有一件事我不明白。

为什么文件和实际的DBL_MANT_DIG= 53?

而根据同一维基百科=52。
而你的代码 似乎也暗示着它是52?

你有没有试着自己去寻找问题的答案?

提示:在谷歌搜索中,输入 "DBL_MANT_DIG 53 52"。