Wow - cool ! Merci. Et j'ai pensé - ça compte à chaque fois. Oui, eh bien, c'est logique, on peut déjà le calculer au moment de la compilation. Donc, comme ça :
Mais il serait plus correct d'écrireDBL_MANT_DIG au lieu de 53.
Cas de gain minimal, si toutes les valeurs du double sont fractionnaires.
1. Votre implémentation est incomplète, elle ne peut être utilisée que si la gamme des valeurs possibles est connue à l'avance.
Voici le code de l'implémentation complète
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.0if(!dbl.ul)
return(1.0);
//--- отрицательные округляем до -0.0return(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.2716:11:15.014 TestRound (EURUSD,H1) Время выполнения ceil = 6.382 наносекунд, Контрольная сумма = 5071042018.08.2716:11:15.028 TestRound (EURUSD,H1) Время выполнения Ceil = 4.792 наносекунд, Контрольная сумма = 507104
2. Les fonctions auto-écrites sont significativement plus lentes que les fonctions intégrées lorsqu'elles sont compilées pour le débogage, lorsque les optimisations sont désactivées.
1. Votre implémentation est incomplète et ne peut être utilisée que si la gamme des valeurs possibles est connue à l'avance.
Voici le code pour l'implémentation complète
2. Les fonctions auto-écrites sont beaucoup plus lentes que les fonctions intégrées lors de la compilation pour le débogage lorsque les optimisations sont désactivées.
Je voulais spéculer sur le thème : vous ne pouvez pas comprendre la Russie avec votre esprit, mais j'ai ensuite porté mon attention sur le thème : implémentations alternatives de fonctions/approches standard.
En général, en ce qui concerne le sujet du fil de discussion, j'ai réussi à mettre en œuvre une approche complètement différente du dessin sur toile. Sans utiliser la classe CCanvas.
Il ne s'agit pas de modifier un ensemble distinct de fonctions, mais de créer un mécanisme de dessin complet, constitué d'un seul bloc.
(Bien sûr, je peux difficilement démontrer tout cela dans le code, parce qu'il y a beaucoup de code et qu'il est écrit de manière non standard, mais je voudrais vous en parler en général).
Donc :
1. le bloc (fonction)
void Нарисовать_элемент(int Канвас, int Элемент = 0)
n'accepte que 2 paramètres - Kanvas et Element.
Kanvas est un objet MT,
L'élément est un dessin.
2. Chaque objet MT a sa propre ressource qui lui est attribuée. Elle est immédiatement chargée dans le "tableau de pixels" à l'aide de ResourceReadImage() ; Si la ressource n'existe pas encore, un drapeau est activé, ce qui déterminera ensuite la portée du cycle sur le noyau.
3. le noyau, est un tableau de propriétés de tous les éléments. Il contient des données sur la taille des objets, et les couleurs pour différents états. Et beaucoup d'autres données. Il y a 235 propriétés au total pour chaque objet. En même temps, chaque élément (selon le type) peut contenir de un à 11 objets (il n'y a pas de limitation).
4. Dans le bloc Dessin, chaque objet implique un "Détail" du dessin. Ainsi, le cycle par objet dans le noyau, est un cycle de dessin dans lequel l'image de chaque détail est créée. Si un Canvas n'a pas encore été créé, un cycle complet est effectué sur tous les détails de ce seul Canvas. L'affiliation aux Kanvas est prescrite dans le noyau, pour chaque Détail. C'est-à-dire que tous les Kanvases, (et les pièces) ont leurs propres numéros d'ordre. Grâce à ces chiffres, il est possible de tirer le contenu des seuls Kanvas requis.
4. Si un Kanvas existe déjà et que son image est chargée dans un tableau de pixels, et que nous n'avons besoin de redessiner qu'un seul élément (sur un événement de changement de couleur, par exemple), alors la portée de la boucle centrale est réduite aux limites de l'élément unique dont le numéro a été obtenu par la fonction de dessin.
Le dessin lui-même est simple. C'est un cycle à travers les cellules d'un tableau unidimensionnel de gauche à droite. Avant que le cycle ne soit réglé :
1. La cellule de départ (point A).
2. La cellule terminale (Point B).
3. Passez à autre chose.
Il est difficile de résumer en quelques mots le fonctionnement d'un bloc de 1500 lignes de code. Il s'agit d'une seule fonction, qui se développe et se polit depuis 20 mois. Je le connais presque par cœur, ce qui me permet de continuer à le développer facilement.
En utilisant le noyau et le focus (en mettant les variables importantes sur la portée globale), le bloc acquiert d'énormes possibilités. Leurs limites ne sont pas visibles pour moi à ce jour.
C'est l'alternative à l'approche standard du dessin sur kanvas.
zy. Si les détails vous intéressent, je peux vous expliquer.
1. Votre implémentation est incomplète et ne peut être utilisée que si la gamme des valeurs possibles est connue à l'avance.
Voici le code pour l'implémentation complète
Merci encore une fois pour le code. Je me suis posé des questions sur ces masques de bits comme le double. Il s'avère que ce n'est pas aussi facile que je le pensais auparavant. J'ai légèrement adapté ma version à la vôtre. Il n'y avait qu'une seule différence : votre version retournait aux valeurs -1>x>0 Ceil(-0.1)= - 0.0, alors que la mienne retournait 0.0. Bien que je ne sache pas quand cela peut être utile.
Même chose, mais lisible et avec des commentaires :
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; // добавляем к бездробной части 1elseif(x>-1 && x<0) // Если -1 < x < 0return -0.0; // то возвращаем -0.0elsereturn (double)long(x);
}
J'ai écrit un script (ci-joint), qui confirme à 100% l'identité avec votre version. Mais cette variante est plus rapide, plus compacte et, à mon avis, plus lisible.
Notez que pas une seule variable n'est créée dans le corps de la fonction, alors que votre version crée 4 variables de 8 octets. Peut-être que je me trompe ?
Résultats lorsque l'entrée x a toujours une partie fractionnaire :
2018.08.2718:42:37.616 TestCeil (EURUSD,M1) Время выполнения функции CeilI = 1.321 наносекунд, Контрольная сумма = 5250492895.02018.08.2718:42:37.619 TestCeil (EURUSD,M1) Время выполнения функции CeilN = 1.094 наносекунд, Контрольная сумма = 5250492895.02018.08.2718:42:37.623 TestCeil (EURUSD,M1) Время выполнения функции ceil = 2.962 наносекунд, Контрольная сумма = 5250492895.02018.08.2718:42:37.623 TestCeil (EURUSD,M1) Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать
Les résultats lorsque l'entrée x a une partie fractionnaire sont rares :
2018.08.2718:49:45.734 TestCeil (EURUSD,M1) Время выполнения функции CeilI = 0.307 наносекунд, Контрольная сумма = 1.15583114403606 e+232018.08.2718:49:45.736 TestCeil (EURUSD,M1) Время выполнения функции CeilN = 0.102 наносекунд, Контрольная сумма = 1.15583114403606 e+232018.08.2718:49:45.738 TestCeil (EURUSD,M1) Время выполнения функции ceil = 1.026 наносекунд, Контрольная сумма = 1.15583114403606 e+232018.08.2718:49:45.738 TestCeil (EURUSD,M1) Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать
Ilyas:
2. Les fonctions auto-écrites sont significativement plus lentes que les fonctions intégrées lors de la compilation pour le débogage, lorsque les optimisations sont désactivées.
La raison pour laquelle la vitesse est nécessaire pour le débogage n'est pas claire. Mais si vous en avez vraiment besoin, vous pouvez utiliser la construction :
#ifdef _DEBUG x=Ceil(y);
#else x=ceil(y); #endif
Et il y a encore une chose que je ne comprends pas :
Pourquoi la documentation et la réalité DBL_MANT_DIG = 53 ?
comme selon le même Wikipedia= 52. Et, comme, il résulte de votre code que 52 aussi ?
Wow - cool ! Merci. Et j'ai pensé - ça compte à chaque fois. Oui, eh bien, c'est logique, on peut déjà le calculer au moment de la compilation.
Donc, comme ça :
Mais il serait plus correct d'écrireDBL_MANT_DIG au lieu de 53.
Cas de gain minimal, si toutes les valeurs du double sont fractionnaires.
1. Votre implémentation est incomplète, elle ne peut être utilisée que si la gamme des valeurs possibles est connue à l'avance.
Voici le code de l'implémentation complète
2. Les fonctions auto-écrites sont significativement plus lentes que les fonctions intégrées lorsqu'elles sont compilées pour le débogage, lorsque les optimisations sont désactivées.
1. Votre implémentation est incomplète et ne peut être utilisée que si la gamme des valeurs possibles est connue à l'avance.
Voici le code pour l'implémentation complète
2. Les fonctions auto-écrites sont beaucoup plus lentes que les fonctions intégrées lors de la compilation pour le débogage lorsque les optimisations sont désactivées.
Merci beaucoup, Ilyas, pour cet excellent code.
Bien sûr, c'est une grande aide ici.
Je l'étudie.
Ce n'est pas la même chose ?Nikolaï, salut. Je vois que vous travaillez sur les graphiques, mais je ne comprends pas bien quelle est la tâche réelle. Sur quoi travaillez-vous ?
Accélérer les fonctions de rendu ?
En général, en ce qui concerne le sujet du fil de discussion, j'ai réussi à mettre en œuvre une approche complètement différente du dessin sur toile. Sans utiliser la classe CCanvas.
Il ne s'agit pas de modifier un ensemble distinct de fonctions, mais de créer un mécanisme de dessin complet, constitué d'un seul bloc.
(Bien sûr, je peux difficilement démontrer tout cela dans le code, parce qu'il y a beaucoup de code et qu'il est écrit de manière non standard, mais je voudrais vous en parler en général).
Donc :
1. le bloc (fonction)
n'accepte que 2 paramètres - Kanvas et Element.
2. Chaque objet MT a sa propre ressource qui lui est attribuée. Elle est immédiatement chargée dans le "tableau de pixels" à l'aide de ResourceReadImage() ; Si la ressource n'existe pas encore, un drapeau est activé, ce qui déterminera ensuite la portée du cycle sur le noyau.
3. le noyau, est un tableau de propriétés de tous les éléments. Il contient des données sur la taille des objets, et les couleurs pour différents états. Et beaucoup d'autres données. Il y a 235 propriétés au total pour chaque objet. En même temps, chaque élément (selon le type) peut contenir de un à 11 objets (il n'y a pas de limitation).
4. Dans le bloc Dessin, chaque objet implique un "Détail" du dessin. Ainsi, le cycle par objet dans le noyau, est un cycle de dessin dans lequel l'image de chaque détail est créée. Si un Canvas n'a pas encore été créé, un cycle complet est effectué sur tous les détails de ce seul Canvas. L'affiliation aux Kanvas est prescrite dans le noyau, pour chaque Détail. C'est-à-dire que tous les Kanvases, (et les pièces) ont leurs propres numéros d'ordre. Grâce à ces chiffres, il est possible de tirer le contenu des seuls Kanvas requis.
4. Si un Kanvas existe déjà et que son image est chargée dans un tableau de pixels, et que nous n'avons besoin de redessiner qu'un seul élément (sur un événement de changement de couleur, par exemple), alors la portée de la boucle centrale est réduite aux limites de l'élément unique dont le numéro a été obtenu par la fonction de dessin.
Le dessin lui-même est simple. C'est un cycle à travers les cellules d'un tableau unidimensionnel de gauche à droite. Avant que le cycle ne soit réglé :
1. La cellule de départ (point A).
2. La cellule terminale (Point B).
3. Passez à autre chose.
Il est difficile de résumer en quelques mots le fonctionnement d'un bloc de 1500 lignes de code. Il s'agit d'une seule fonction, qui se développe et se polit depuis 20 mois. Je le connais presque par cœur, ce qui me permet de continuer à le développer facilement.
En utilisant le noyau et le focus (en mettant les variables importantes sur la portée globale), le bloc acquiert d'énormes possibilités. Leurs limites ne sont pas visibles pour moi à ce jour.
C'est l'alternative à l'approche standard du dessin sur kanvas.
zy. Si les détails vous intéressent, je peux vous expliquer.
Voici à quoi ressemble le début du bloc :
1. Votre implémentation est incomplète et ne peut être utilisée que si la gamme des valeurs possibles est connue à l'avance.
Voici le code pour l'implémentation complète
Merci encore une fois pour le code. Je me suis posé des questions sur ces masques de bits comme le double. Il s'avère que ce n'est pas aussi facile que je le pensais auparavant.
J'ai légèrement adapté ma version à la vôtre. Il n'y avait qu'une seule différence : votre version retournait aux valeurs -1>x>0 Ceil(-0.1)= - 0.0, alors que la mienne retournait 0.0. Bien que je ne sache pas quand cela peut être utile.
Et vous obtenez ce qui suit :
Même chose, mais lisible et avec des commentaires :
J'ai écrit un script (ci-joint), qui confirme à 100% l'identité avec votre version.
Mais cette variante est plus rapide, plus compacte et, à mon avis, plus lisible.
Notez que pas une seule variable n'est créée dans le corps de la fonction, alors que votre version crée 4 variables de 8 octets.
Peut-être que je me trompe ?
Résultats lorsque l'entrée x a toujours une partie fractionnaire :
Les résultats lorsque l'entrée x a une partie fractionnaire sont rares :
2. Les fonctions auto-écrites sont significativement plus lentes que les fonctions intégrées lors de la compilation pour le débogage, lorsque les optimisations sont désactivées.
La raison pour laquelle la vitesse est nécessaire pour le débogage n'est pas claire.
Mais si vous en avez vraiment besoin, vous pouvez utiliser la construction :
Et il y a encore une chose que je ne comprends pas :
Pourquoi la documentation et la réalité DBL_MANT_DIG = 53 ?
comme selon le même Wikipedia= 52.
Et, comme, il résulte de votre code que 52 aussi ?
Nikolaï, salut. Je vois que vous travaillez sur les graphiques, mais je ne comprends pas bien quelle est la tâche réelle. Sur quoi travaillez-vous ?
Accélérer les fonctions de rendu ?
Bonjour Piotr !
Je répondrai en personne.
Et il y a encore une chose que je ne comprends pas :
Pourquoi la documentation et la réalité DBL_MANT_DIG = 53 ?
alors que selon le même wikipedia= 52.
Et il semble que votre code implique également que c'est 52 ?
Avez-vous essayé de trouver vous-même la réponse à cette question ?
Conseil : dans la recherche google, tapez "DBL_MANT_DIG 53 52".