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

 
Nikolai Semko:

Sí, pero si:

entonces está bien.

Queda por ver si está bien para cualquier número x
 

A100:

void OnStart()
{
        Print( (int)(3.0001 + 0.999999999999999)); //все равно 4
        Print( floor(3.00001));                    //3
}




No lo entiendo. ¿Cuál es el problema?

 
A100:
Queda por ver si estará bien para cualquier número x

Por supuesto que no...

Después de todo, si esto sucede:

double x=3;
x=x+0.1;
x=x+0.1;
x=x+0.1;
x=x+0.1;
if (x!=3.4) Print("oppps..."); // oppps...

entonces, las preguntas no son para mí ni para esta idea.

 
Nikolai Semko:
¿Cuál es el problema?
void OnStart()
{
        double d =  16 + 0.999999999999999;
        Print( (int)(d + 0.999999999999999)); //18
        Print( (int)ceil( d ));               //17
}
 
A100:

ver mi post anterior

 
Nikolai Semko:
entonces, las preguntas no son para mí, ni para esta idea.
floor(), ceil(), round() están ahí para evitar preguntas
 

Creo que todos estos fallos anteriores están fuera del alcance del uso práctico de esta solución para acelerar el redondeo de enteros positivos, porque poca gente necesita precisión a nivel de 16 dígitos. Y estos fallos surgen de todo tipo de desbordamientos en los niveles de puntos del propio compilador.

 
A100:
Floor(), ceil(), round() están ahí para ese propósito - así que no hay preguntas

No te estoy prohibiendo que los uses. Puede utilizarlos. Yo mismo los utilizaré. Pero si creo un algoritmo donde la velocidad es importante, utilizaré esta variante de redondeo teniendo en cuenta todos los matices de este método. Creo que sería útil para otros programadores conocer la existencia de esta alternativa. La discusión es exactamente lo que necesitamos saber sobre los matices de este método de redondeo. Muchas gracias por ello. ¿No tengo razón?

 
Nikolai Semko:

DBL_MIN yDBL_EPSILON no funcionan: son demasiado pequeños. Quizás tenga sentido dejar 0,999999999999999999 (16 nueves - el número máximo de dígitos después del punto decimal en el doble)

Así, DBL_EPSILON tiene 16 decimales:2,2204460492503131e-016.

En tu caso, en realidad te llevas una, ya que la diferencia es sólo 1e-16, que es 2 veces menos que epsilon.

 
Alexey Navoykov:

Así que DBL_EPSILON tiene 16 decimales:2,2204460492503131e-016

Y en tu caso sí que lo consigues, ya que la diferencia es sólo de 1e-16, que es 2 veces menos que epsilon.


Sí, lo entiendo, pero no funciona. Resulta que tampoco funciona con 16 nueves (extraño, antes parecía funcionar). Sólo funciona con 15 nueves.

double x=3;
int Y=(int)ceil(x);
Print(Y);                         // 3
Y=(int)(x+0.999999999999999); 
Print(Y);                         // 3  (15 9-ток)
Y=(int)(x+0.9999999999999999);
Print(Y);                         // 4  (16 9-ток)
Y=(int)(x+1-DBL_EPSILON);
Print(Y);                         // 4
Razón de la queja: