標準的な機能/アプローチの代替実装 - ページ 12

 
Nikolai Semko:

わー、かっこいいー。ありがとうございます。そして、思ったのは、「毎回数えている」ということです。うん、まあ、論理的には、コンパイルの段階ですでに計算できるわけですからね。
だから、こんな風に。

しかし、53ではなく、DBL_MANT_DIGと 書いた方が正しいでしょう。

doubleの値がすべて小数である場合、利得が最小となるケース。

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さん、素晴らしいコードをどうもありがとうございました。

もちろん、ここでも大活躍です。

勉強しているところです。

同じこと ではありませんか?
 
Nikolai Semko:


ニコライさん、こんにちは。グラフィックを担当されているようですが、実際にどのような作業をされているのかがよくわかりません。何をやっているんですか?

レンダリング機能の高速化?

 
ロシアは頭で理解できない」というテーマを推測したかったのですが、「標準機能/アプローチの代替実装」というテーマに目を向けました。
 

一般的に、このスレッドのトピックでは、私はキャンバスに描画するための完全に別のアプローチを実装することに成功しました。CCanvas クラスを 使用しない場合。

つまり、個別の機能を修正するのではなく、1つのブロックで構成される完全な描画機構を作るということです。

(もちろん、コードが多く、非標準的な書き方をしているので、コードですべてを示すことはほとんどできませんが、一般的なことをお伝えしたいと思います)。

だから

1. ブロック(機能)

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

は、KanvasとElementの2つのパラメータのみを受け付けます。

  • Kanvasは MT-Objectです。
  • Elementは 図面です。

2.MT-オブジェクトには、それぞれリソースが割り当てられている。リソースがまだ存在しない場合、フラグが立てられ、その後カーネル上のサイクルの範囲が決定される。

3. カーネルは、全要素のプロパティの配列である。物体の大きさや、状態別の色などのデータが含まれています。その他、様々なデータを掲載しています。すべてのオブジェクトには、合計で235のプロパティがあります。同時に、各エレメント(タイプによる)には1~11個のオブジェクトを含めることができる(制限はない)。

4.図面ブロックでは、各オブジェクトは図面の「詳細」を意味する。したがって、カーネル内のオブジェクトによるサイクルは、各Detailの画像を作成する描画サイクルとなる。キャンバスがまだ作成されていない場合は、そのキャンバスの全ディテールだけで1サイクルが行われます。カンヴァへの所属は、ディテールごとにカーネルに規定されています。つまり、すべてのKanvase、(およびParts)には、それぞれ固有のシーケンス番号があります。この数字によって、必要なKANVASの内容だけを描き出すことができるのです。

4.Kanvasが既に存在し、その画像がピクセルの配列でロードされており、単一の要素だけを再描画する必要がある場合(例えば、色変更イベントで)、コアループの範囲は、描画関数で取得した番号を持つ単一の要素の境界まで狭められます。


図面そのものはシンプルです。一次元配列のセルを左から右へ循環させるものである。サイクルが設定される前。

1.スタート地点のセル(A点)。

2.エンドセル(B点)。

3.踏み倒す。

1500行のコードブロックの動作を一言でまとめるのは難しい。20カ月間、成長し、磨きをかけてきた1つの機能です。ほとんど暗記しているので、開発し続けることが容易なのです。

カーネルとフォーカス(重要な変数をグローバルスコープに置くこと)を使うことで、ブロックは大きな可能性を手に入れることができます。その限界は、今も私には見えていません。

つまり、標準的なカンヴァス描画の手法に代わるものですね。


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%同一であることを確認しました。
しかし、このバリエーションは、より速く、よりコンパクトで、より読みやすいと私は思っています。

関数本体には変数が1つも作成されていませんが、あなたのバージョンでは8バイトの変数が4つ作成されていることに注意してください。
もしかしたら、私が間違っているのかも?

入力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:

ニコライさん、こんにちは。グラフィックを担当されているようですが、実際にどのような作業をされているのかがよくわかりません。何をやっているんですか?

レンダリング機能の高速化?

ピョートルさん、こんにちは。
直接返信します。

 
 
Nikolai Semko:
そして、もうひとつわからないことがあります。

ドキュメントと実際のDBL_MANT_DIG = 53はなぜですか?

一方、同じウィキペディアに よると=52。
そして、あなたのコードも 52であることを暗示しているようです?

自分で答えを見つけようとしたことがありますか?

ヒント:google検索で「DBL_MANT_DIG 53 52」と入力してください。

理由: