c++ - solucionario - estadistica aplicada a los negocios y la economia ejercicios resueltos
¿Por qué muchos programas(antiguos) usan floor(0.5+input) en lugar de round(input)? (5)
Las diferencias residen en el valor devuelto que proporciona entradas sobre el desempate, creo, como este código :
int main()
{
std::cout.precision(100);
double input = std::nextafter(0.05, 0.0) / 0.1;
double x1 = floor(0.5 + input);
double x2 = round(input);
std::cout << x1 << std::endl;
std::cout << x2 << std::endl;
}
que salidas:
1
0
Pero al final son solo resultados diferentes, uno elige su preferido.
Veo muchos programas "antiguos" de C / C ++ que usan
floor(0.5 + input)
lugar de
round(input)
.
¿Hay alguna razón histórica? ¿Más barato en la CPU?
Creo que aquí es donde te equivocas:
Pero al final son solo resultados diferentes, uno elige su preferido. Veo muchos programas "antiguos" de C / C ++ que usan floor (0.5 + input) en lugar de round (input).
Ese no es el caso.
Debe seleccionar
el esquema de redondeo correcto para el dominio
.
En una aplicación financiera, redondeará usando las reglas del banquero (por cierto, no usar flotante).
Sin embargo, cuando se muestrea, el redondeo utilizando
static_cast<int>(floor(f + .5))
produce menos ruido de muestreo, esto incrementa el rango dinámico.
Al alinear píxeles, es decir, convertir una posición en coordenadas de pantalla, usar cualquier otro método de redondeo producirá agujeros, huecos y otros artefactos.
Muchos programadores adaptan modismos que aprendieron al programar con otros lenguajes.
No todos los idiomas tienen una función
round()
, y en esos idiomas es normal usar
floor(x + 0.5)
como sustituto.
Cuando estos programadores comienzan a usar C ++, no siempre se dan cuenta de que hay una
round()
incorporada
round()
, continúan usando el estilo al que están acostumbrados.
En otras palabras, solo porque vea un montón de código que hace algo, no significa que haya una buena razón para hacerlo. Puede encontrar ejemplos de esto en cada lenguaje de programación. Recuerde la ley de Sturgeon :
noventa por ciento de todo es basura
No hay razón histórica alguna. Este tipo de desviación ha existido desde el año. La gente hace esto cuando se sienten muy, muy traviesos. Es un abuso grave de la aritmética de coma flotante, y muchos programadores profesionales experimentados caen en la trampa. Incluso los cuerpos de Java hicieron hasta la versión 1.7. Chicos divertidos.
Mi conjetura es que una función de redondeo alemana decente lista para usar no estaba disponible formalmente hasta C ++ 11 (a pesar de que C obtuvo la suya en C99), pero eso realmente no es excusa para adoptar la llamada alternativa.
Aquí está la cosa: ¡
floor(0.5 + input)
no siempre recupera el mismo resultado que la llamada
std::round
correspondiente!
La razón es bastante sutil: el punto de corte para un redondeo alemán,
a.5
para un número entero
a
es, por una coincidencia de propiedad del universo, un
racional diádico
.
Como esto se puede representar exactamente en un punto flotante IEEE754 hasta la potencia 52 de 2, y de ahí en adelante el redondeo no funciona,
std::round
siempre funciona correctamente.
Para otros esquemas de coma flotante, consulte la documentación.
Pero agregar
0.5
a un
double
puede introducir imprecisión causando un ligero bajo o sobreimpulso para algunos valores.
Si lo piensa, agregar dos valores
double
juntos, que son el inicio de conversiones denatorias involuntarias, y aplicar una función que es una función muy fuerte de la entrada (como una función de redondeo), seguramente terminará en lágrimas.
No lo hagas
Referencia: ¿Por qué Math.round (0.49999999999999994) devuelve 1
Una razón simple podría ser que existen diferentes métodos para redondear números, por lo que, a menos que conozca el método utilizado, podría obtener resultados diferentes.
Con floor (), puede ser coherente con los resultados. Si el flotador es .5 o mayor, agregarlo aumentará al siguiente int. Pero .49999 solo dejará caer el decimal.
std::round
se introduce en C ++ 11.
Antes de eso, solo estaba disponible
std::floor
por lo que los programadores lo usaban.