Vitesse d'exécution des fonctions ceil(),round(),floor() - page 5

 
Nikolai Semko:


Bien sûr, vous avez raison. Mais je vais le répéter. Pour 99,9% des tâches, il est absolument correct de remplacer les fonctions d'arrondi par une variante alternative plus rapide utilisant la conversion des types de fraction en (int) ou (long). Un programmeur expérimenté doit simplement être conscient de ce fait et l'appliquer quand c'est opportun.

Dans 99% des cas, il n'est pas nécessaire de se préoccuper des arrondis. Pour les comparaisons de prix, j'ai cette absurdité :

// 0 - first is greater than second
// 1 - equal
// 2 - second is greater than first
uchar compare_prices(double first, double second)
{
   if(first - second >= _Point)
      return 0;
   if(second - first >= _Point)
      return 2;

   first = round(first/_Point);
   second = round(second/_Point);
   
   if(first > second)
      return 0;
   if(first < second)
      return 2;
   return 1;
}

Vous pouvez remarquer que dans la plupart des cas, il n'arrivera pas du tout à round(), bien que je n'aie pas mesuré la vitesse.

 
Nikolai Semko:

voir ci-dessus

lorsque x = 3 (n'importe quel nombre entier), il y a une confiture :))

Est-ce la mienne ou votre formule qui a un joint ?

Respectueusement.
 
Andrey Kisselyov:
Y a-t-il un bug dans la mienne ou dans votre formule ?

Respectueusement.

Dans mon ancien :

y=ceil(x);  -> y=(int)(x+1);

et dans le vôtre :

y=ceil(x);  -> y=(int)(x)+1;

quand x=3, dans les deux cas, la valeur de 4 sera fausse.

et la variante :

y=ceil(x);  -> y=(int)(x+0.9999999999999997);

est jusqu'à présent le plus correct tout en maintenant une vitesse d'exécution maximale.

 
Nikolai Semko:

Dans mon ancien :

et dans le vôtre :

à x=3 dans les deux cas il y aura une valeur incorrecte de 4

et en cas de variante :

est jusqu'à présent la plus correcte tout en maintenant une vitesse d'exécution maximale.

mais pourquoi avez-vous besoin de cette formule lorsque vous donnez un nombre entier à son entrée ?

avec respect.

P.S. vous devez comprendre, si vous voulez être un bon programmeur, qu'il n'est pas nécessaire de pousser partout et pas toujours toutes sortes de fonctions accélératrices, cela dépend de la tâche à accomplir et de l'algorithme avec lequel vous travaillez.
 
Andrey Kisselyov:

Mais pourquoi avez-vous besoin de cette formule lorsque vous donnez un nombre entier à son entrée ?

Sincèrement.


Vous ne savez peut-être pas s'il s'agit d'un entier ou d'un non-entier. Dans certains cas, un nombre double peut devenir un nombre entier.

 
Andrey Kisselyov:

P.S. Vous devez comprendre, si vous voulez être un bon programmeur, que vous n'avez pas besoin partout et pas toujours de pousser toutes sortes de fonctions accélératrices, cela dépend de la tâche à accomplir et de l'algorithme avec lequel vous travaillez.

Bien sûr. C'est pourquoi j'ai écrit "appliquer quand c'est approprié".
 
Nikolai Semko:

Vous ne savez peut-être pas s'il s'agit d'un entier ou d'un non-entier. Il y a des moments où un nombre peut devenir un nombre entier.

Ensuite, allez directement à vos variantes de chiffres d'entrée.
if(x-(int)(x)>0)y=(int)(x)+1;
else y=x;

Respectueusement.

P.S. Le double par définition ne peut pas être un nombre entier, la représentation d'un nombre dans la mémoire de la machine ne changera pas.
 
Andrey Kisselyov:
Ensuite, vous devez faire tout un plat de vos choix de chiffres sur l'entrée.

respectueusement.


c'est pour ça, pour qu'on n'ait pas à en faire tout un plat :

if(x-(int)(x)>0)y=(int)(x)+1;
else y=x;

C'est plus facile à écrire :

y=(int)(x+0.9999999999999997);

ou ceci.

#define _ceil(x)  (int)((x)+0.9999999999999997)
...
y=_ceil(x);
 
Nikolai Semko:

donc tu n'as pas besoin d'en faire tout un plat :

c'est plus facile à écrire :

à l'adresse
1-0.9999999999999998

vous n'y arriverez pas.
Avec cette approche, vous pouvez trouver un nombre à partir duquel votre formule ne fonctionnera pas.

Respectueusement.

 
Andrey Kisselyov:
à l'adresse

Ça ne va pas marcher.
Avec cette approche, vous trouverez un nombre à partir duquel votre formule ne fonctionnera pas.

Respectueusement.


J'en ai déjà parlé ici.

Je vous suggère de relire ce fil pour ne pas vous répéter.