표준 기능/접근법의 대체 구현 - 페이지 12

 
Nikolai Semko :

와 멋있다! 고맙습니다. 그리고 저는 생각했습니다. 모든 시간이 중요합니다. 네, 논리적입니다. 이미 컴파일 단계에서 계산할 수 있습니다.
다음과 같이:

사실, 53 대신 DBL_MANT_DIG 를 쓰는 것이 더 정확할 것입니다.

모든 이중 값이 소수인 경우 최소 승리 사례입니다.

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. 자체 작성 함수는 최적화가 비활성화되어 있을 때 디버깅을 위해 컴파일할 때 내장 함수보다 훨씬 느립니다.

훌륭한 코드에 대해 Ilyas에게 대단히 감사합니다.

물론 여기에는 Union이 큰 도움이 됩니다.

공부중...

위협 그리고 옵션은 확실히 동일하지 않습니까?
 
Nikolai Semko :


니콜라스, 안녕. 나는 당신이 그래픽에 종사하는 것을 알지만 실제로 작업이 무엇인지 완전히 이해하지 못합니다. 무슨 일을하고 있니?

렌더링 기능의 속도를 높이시겠습니까?

 
나는 주제에 대해 추측하고 싶었습니다. 러시아는 마음으로 이해할 수 없지만 주제에 관심을 끌었습니다. 표준 기능 / 접근 방식의 대안 구현.
 

일반적으로 분기 주제에 대해 이야기하면서 캔버스에 그리는 완전히 대안적인 접근 방식을 구현했습니다. CCanvas 클래스 를 사용하지 않습니다.

즉, 별도의 기능 집합을 수정하는 것이 아니라 단일 블록으로 구성된 통합 그리기 메커니즘을 만드는 것입니다.

(물론 코드가 많고 비표준으로 작성되어 있기 때문에 이 모든 것을 코드로 보여주기는 어렵지만 일반적인 용어로 말씀드리고 싶습니다.)

그래서:

1. 차단(기능)

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

Canvas와 Element의 2가지 매개변수만 사용합니다.

  • Canvas 는 MT 객체이며,
  • 요소 - 그림.

2. 각 MT-object는 자체 리소스를 가지고 있습니다. ResourceReadImage()를 사용하여 "픽셀 배열"에 즉시 로드됩니다. 리소스가 아직 존재하지 않으면 나중에 코어를 통한 루프 범위를 결정하는 플래그가 설정됩니다.

3. 핵심, - 모든 요소의 속성 배열. 또한 개체의 크기와 다양한 상태의 색상에 대한 데이터도 포함합니다. 그리고 다른 많은 데이터. 각 개체에 대해 총 235개의 속성이 있습니다. 동시에 각 요소(유형에 따라 다름)는 1개에서 11개까지의 개체를 포함할 수 있습니다(제한 없음).

4. 도면 블록에서 각 개체는 도면의 "상세"를 의미합니다. 따라서 코어에 있는 객체를 통한 주기는 각 Part의 이미지가 생성되는 드로잉 주기입니다. Canvas가 아직 생성되지 않은 경우 이 Canvas의 모든 세부 정보에 대해서만 전체 주기가 만들어집니다. 각 Detail에 대해 Core에 Canvas에 속해 있음을 등록합니다. 즉, 모든 캔버스(및 세부 정보)에는 일련 번호가 있습니다. 이 숫자를 통해 원하는 Canvas의 내용만 그릴 수 있습니다.

4. Canvas가 이미 존재하고 해당 이미지가 픽셀 배열에 로드되고 단일 요소(예: 색상 변경 이벤트)만 다시 그려야 하는 경우 코어를 통과하는 루프 범위가 경계로 좁아집니다. 하나의 요소 중 하나의 숫자는 그리기 기능으로 얻은 것입니다.


그림 자체는 간단합니다. 이것은 1차원 배열의 셀을 왼쪽에서 오른쪽으로 순환하는 것입니다. 주기가 설정되기 전:

1. 초기 셀(포인트 A).

2. 끝 세포(B 지점).

3. 건너뛰기.

1500줄의 코드로 구성된 블록의 동작을 간략하게 설명하기는 어렵다. 이것은 20개월 동안 성장하고 연마한 기능 중 하나입니다. 나는 그것을 거의 마음으로 알고 있기 때문에 개발을 계속하기 쉽습니다.

커널과 포커스를 사용하여(중요한 변수를 전역 범위에 두는) 블록은 엄청난 힘을 얻습니다. 그들의 경계는 오늘날까지 나에게 보이지 않습니다.

이것은 캔버스에 그리는 표준 접근 방식에 대한 대안입니다.


추신 세부 사항에 관심이 있으시면 설명할 수 있습니다.

 

블록의 시작 부분은 다음과 같습니다.

 //+------------------------------------------------------------------+
//|                                                     Анимация.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인 이유는 무엇입니까?

동일한 Wikipedia 에 따르면   = 52.
그리고 귀하의 코드 에서 52 ?

파일:
TestCeil.mq5  15 kb
 
Реter Konow :

니콜라스, 안녕. 나는 당신이 그래픽에 종사하는 것을 알지만 실제로 작업이 무엇인지 완전히 이해하지 못합니다. 무슨 일을하고 있니?

렌더링 기능의 속도를 높이시겠습니까?

이봐 피터!
비공개로 답변드리겠습니다.

 
 
Nikolai Semko :
그리고 여전히 한 가지 오해가 있습니다.

문서와 실제로 DBL_MANT_DIG = 53인 이유는 무엇입니까?

동일한 Wikipedia 에 따르면   = 52.
그리고 코드 에서 52 ?

스스로 답을 찾아보셨나요?

힌트: Google 검색창에 "DBL_MANT_DIG 53 52"를 입력하세요.