Standart özelliklerin/yaklaşımların alternatif uygulamaları - sayfa 12

 
Nikolai Semko :

Vay havalı! Teşekkür ederim. Ve düşündüm - her zaman önemlidir. Evet, mantıklı, derleme aşamasında zaten hesaplayabilirsiniz.
Sonra şöyle:

Doğru, 53 yerine DBL_MANT_DIG yazmak daha doğru olur.

Tüm çift değerler kesirli ise minimum kazanma durumu.

1. Uygulamanız eksik, ancak olası değerlerin aralığı önceden biliniyorsa kullanılabilir.

İşte tam uygulama kodu

 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. Kendi kendine yazılan işlevler, optimizasyonlar devre dışı bırakıldığında hata ayıklama için derlendiğinde yerleşik işlevlerden çok daha yavaştır.

 
Ilyas :

1. Uygulamanız eksik, ancak olası değerlerin aralığı önceden biliniyorsa kullanılabilir.

İşte tam uygulama kodu

2. Kendi kendine yazılan işlevler, optimizasyonlar devre dışı bırakıldığında hata ayıklama için derlendiğinde yerleşik işlevlerden çok daha yavaştır.

Harika kod için çok teşekkür ederim İlyas.

Elbette sendika burada büyük bir yardımcıdır.

Ders çalışıyorum...

Tehdit Ve bu seçenek kesinlikle aynı değil mi?
 
Nikolai Semko :


Nicholas, merhaba. Grafiklerle uğraştığınızı görüyorum ama aslında görevin ne olduğunu tam olarak anlamıyorum. Ne üzerine çalışıyorsun?

Oluşturma işlevlerini hızlandırmak?

 
Şu konuda spekülasyon yapmak istedim: Rusya akılla anlaşılamaz ama sonra şu konuya dikkat çektim: standart fonksiyonların/yaklaşımların alternatif uygulamaları.
 

Genel olarak, dal konusunda konuşurken, tuval üzerine çizime tamamen alternatif bir yaklaşım uygulamayı başardım. CCanvas sınıfını kullanmamak.

Yani, ayrı bir fonksiyon setini değiştirmek değil, tek bir bloktan oluşan entegre bir çizim mekanizması oluşturmak.

(Tabi tüm bunları kodda pek gösteremiyorum çünkü çok fazla kod var ve standart dışı yazılıyor ama genel hatlarıyla anlatmak istiyorum).

Böyle:

1. Blok (işlev)

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

sadece 2 parametre alır - Canvas ve Element.

  • Tuval bir MT nesnesidir,
  • Öğe - resim.

2. Her MT nesnesinin kendi kaynağı vardır. ResourceReadImage() kullanılarak hemen bir "piksel dizisine" yüklenir; Kaynak henüz mevcut değilse, daha sonra çekirdek boyunca döngü aralığını belirleyecek bir bayrak ayarlanır.

3. Çekirdek, - tüm öğelerin bir dizi özelliği. Ayrıca nesnelerin boyutu ve çeşitli durumlar için renkler hakkında veriler içerir. Ve diğer birçok veri. Her nesne için toplam 235 özellik vardır. Aynı zamanda, her öğe (tipe bağlı olarak) bir ila 11 nesne içerebilir (kısıtlama yoktur).

4. Çizim bloğunda, her nesne çizimin bir "Ayrıntısı" anlamına gelir. Bu nedenle, çekirdekteki nesneler arasındaki döngü, her Parçanın görüntüsünün oluşturulduğu bir çizim döngüsüdür. Kanvas henüz oluşturulmadıysa, yalnızca bu Kanvas'ın tüm Ayrıntıları üzerinden tam bir döngü yapılır. Kanvas'a Ait olmak, her Ayrıntı için çekirdeğe kaydedilir. Yani, tüm Kanvaslar (ve Ayrıntılar) kendi seri numaralarına sahiptir. Bu numaralar sayesinde sadece istenilen Kanvasın içeriğini çizmek mümkündür.

4. Kanvas zaten varsa ve görüntüsü bir piksel dizisine yüklenmişse ve yalnızca tek bir öğeyi yeniden çizmemiz gerekiyorsa (örneğin, bir renk değişikliği olayında), o zaman çekirdekten geçen döngü aralığı sınırlara daralır. sayısı çizim işleviyle elde edilen bir elemanın.


Çizimin kendisi basittir. Bu, tek boyutlu bir dizinin hücreleri arasında soldan sağa bir döngüdür. Döngü ayarlanmadan önce:

1. İlk hücre (A noktası).

2. Uç hücre (B Noktası).

3. Adım atmak.

1500 satır koddan oluşan bir bloğun işleyişini kısaca anlatmak zordur. Bu, 20 aydır büyüyen ve parlayan bir özellik. Neredeyse ezbere biliyorum, bu da gelişimini sürdürmeyi kolaylaştırıyor.

Bir çekirdek ve odak kullanımı (önemli değişkenleri küresel kapsama dahil ederek) yoluyla, blok muazzam bir güç kazanır. Sınırları bu güne kadar bana görünmüyor.

Bu, tuval üzerine çizim yapmak için standart yaklaşıma böyle bir alternatiftir.


not Detaylarla ilgileniyorsanız, açıklayabilirim.

 

Bloğun başlangıcı şöyle görünür:

 //+------------------------------------------------------------------+
//|                                                     Анимация.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. Uygulamanız eksik, ancak olası değerlerin aralığı önceden biliniyorsa kullanılabilir.

İşte tam uygulama kodu

Kod için tekrar çok teşekkürler. Beynimi bu çift tip bit maskeleriyle harap ettim. Daha önce düşündüğüm kadar basit olmadığı ortaya çıktı.
Sürümümü sizinkine uyacak şekilde biraz ayarladım. Tek bir fark vardı: sürümünüz -1>x>0 Ceil(-0.1)= - 0.0 ve benimki 0.0 değerleriyle döndü. Bunun ne zaman yararlı olabileceği gerçek açık değildir.

Ve şunlar oldu:

 //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);}

Aynı, yalnızca okunabilir ve yorumlarla:

 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);
  }

Sürümünüzle çalışmanın %100 özdeşliğini doğrulayan bir komut dosyası (ekli) yazdım.
Ancak aynı zamanda, bu seçenek daha hızlı, daha kompakt ve bana göre daha okunaklı.

Ayrıca, 4 adet 8 baytlık değişken oluştururken, işlev gövdesinde tek bir değişken bile oluşturulmaz.
Belki de ben hatalıyım?

x girişinin her zaman bir kesirli kısmı olduğunda sonuçlar:

 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 girişinde kesirli kısım nadir olduğunda sonuçlar:

 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 ... Прервите скрипт, когда надоест ждать
İlyas :


2. Kendi kendine yazılan işlevler, optimizasyonlar devre dışı bırakıldığında hata ayıklama için derlendiğinde yerleşik işlevlerden çok daha yavaştır.

Hata ayıklamanın neden hız gerektirdiği açık değildir.
Ancak gerçekten ihtiyacınız varsa, bir seçenek olarak inşaatı kullanabilirsiniz:

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


Ve hala bir yanlış anlama var:

Neden belgelerde ve aslında DBL_MANT_DIG = 53?

aynı Wikipedia'ya göre   = 52.
Ve görünüşe göre, kodunuzdan da bunu takip ediyor 52 ?

Dosyalar:
TestCeil.mq5  15 kb
 
Реter Konow :

Nicholas, merhaba. Grafiklerle uğraştığınızı görüyorum ama aslında görevin ne olduğunu tam olarak anlamıyorum. Ne üzerine çalışıyorsun?

İşleme işlevlerini hızlandırmak?

Hey Peter!
özelden cevap vereceğim

 
 
Nikolai Semko :
Ve hala bir yanlış anlama var:

Neden belgelerde ve aslında DBL_MANT_DIG = 53?

aynı Wikipedia'ya göre   = 52.
Ve görünüşe göre, kodunuzdan da bunu takip ediyor 52 ?

Cevabı kendin bulmaya çalıştın mı?

İpucu: google arama çubuğuna "DBL_MANT_DIG 53 52" yazın

Neden: