street solucionario resueltos resuelto que puesto promocional periodicos parte paquete negocios milwaukee los iowa grocery gratis estado estadistica esquina ejercicios edicion economia east compra como comercio cliente churchill carne cantidad camara cada aplicada abarrotes 9th c++ rounding floor

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.