Velocidad de ejecución de las funciones ceil(),round(),floor() - página 5

 
Nikolai Semko:


Por supuesto que tienes razón. Pero lo repetiré. Para el 99,9% de las tareas es absolutamente correcto sustituir las funciones de redondeo por una variante alternativa más rápida que utilice la conversión de tipos fraccionarios a (int) o (long). Un programador experimentado debe ser consciente de este hecho y aplicarlo cuando sea conveniente.

En el 99% de los casos no es necesario preocuparse por el redondeo. Para comparar precios tengo esta tontería:

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

Puedes notar que en la mayoría de los casos no llega a redondear() en absoluto, aunque no he medido la velocidad.

 
Nikolai Semko:

ver arriba

cuando x = 3 (cualquier entero) hay un atasco :))

¿Es la mía o tu fórmula la que tiene una articulación?

Respetuosamente.
 
Andrey Kisselyov:
¿Hay un error en el mío o en su fórmula?

Respetuosamente.

En mi antiguo:

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

y en el tuyo:

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

cuando x=3 en ambos casos será el valor erróneo de 4

y la variante:

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

es hasta ahora la más correcta, manteniendo la máxima velocidad de ejecución.

 
Nikolai Semko:

En mi antiguo:

y en el tuyo:

en x=3 en ambos casos habrá un valor incorrecto de 4

y en caso de variante:

es hasta ahora la más correcta, manteniendo la máxima velocidad de ejecución.

pero, ¿por qué se necesita esta fórmula cuando se da un número entero a su entrada?

con respeto.

P.D. tienes que entender, si quieres ser un buen programador, que no en todas partes y no siempre hay que meter todo tipo de funciones aceleradoras, depende de la tarea que tengas entre manos y del algoritmo con el que estés trabajando.
 
Andrey Kisselyov:

¿Por qué necesitas esta fórmula cuando das un número entero a su entrada?

Sinceramente.


Puede que no sepas si es un entero o un no entero. Hay veces que un número doble puede convertirse en un número entero.

 
Andrey Kisselyov:

P.D. Tienes que entender, si quieres ser un buen programador, que no en todas partes y no siempre necesitas meter todo tipo de funciones aceleradoras, depende de la tarea en cuestión y del algoritmo con el que estés trabajando.

Por supuesto. Por eso escribí "aplicar cuando corresponda".
 
Nikolai Semko:

Puede que no sepas si es un entero o un no entero. Hay veces que un número puede convertirse en un entero.

A continuación, vaya directamente a sus variantes de números de entrada.
if(x-(int)(x)>0)y=(int)(x)+1;
else y=x;

Respetuosamente.

P.D. El doble por definición no puede ser un entero, la representación de un número en la memoria de la máquina no cambiará.
 
Andrey Kisselyov:
Luego hay que hacer un gran esfuerzo para elegir los números de la entrada.

con todo respeto.


por eso, para que no tengamos que darle importancia:

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

Es más fácil escribir:

y=(int)(x+0.9999999999999997);

o esto.

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

así que no hay que darle importancia:

es más fácil escribir:

en
1-0.9999999999999998

no lo harás bien.
Con este enfoque, puedes encontrar un número en el que tu fórmula no funcione.

Respetuosamente.

 
Andrey Kisselyov:
en

No va a funcionar.
Con este enfoque, encontrarás un número a partir del cual tu fórmula no funcionará.

Respetuosamente.


Ya he escrito sobre ello aquí.

Te sugiero que releas este hilo para no repetirte.