Dobles redondos – .5 – sprintf

Estoy usando el siguiente código para redondear a 2dp:

sprintf(temp,"%.2f",coef[i]); //coef[i] returns a double 

Redondea con éxito 6.666 a 6.67, pero no funciona correctamente al redondear 5.555. Devuelve 5.55, mientras que debería (al menos en mi opinión) devolver 5.56.

¿Cómo puedo hacer que se redondee cuando el siguiente dígito es 5? es decir, retorno 5.56.

edición: ahora me doy cuenta de que esto está sucediendo porque cuando entro a 5.555 con cin se guarda como 5.554999997.

Voy a intentar redondear en dos etapas: primero a 3dp y luego a 2dp. ¿Alguna otra idea (más elegante)?

Parece que tienes que usar la función de redondeo matemático para redondear correctamente.

 printf("%.2f %.2f\n", 5.555, round(5.555 * 100.)/100.); 

Esto da el siguiente resultado en mi máquina:

 5.55 5.56 

El número 5.555 no se puede representar como un número exacto en IEEE754. La impresión de la constante 5.555 con "%.50f" da como resultado:

 5.55499999999999971578290569595992565155029300000000 

por lo que será redondeado hacia abajo. Trate de usar esto en su lugar:

 printf ("%.2f\n",x+0.0005); 

aunque debe tener cuidado con los números que se pueden representar exactamente, ya que esta expresión los redondeará de forma incorrecta.

Es necesario comprender las limitaciones de las representaciones de punto flotante. Si es importante que obtenga precisión, puede usar (o codificar) un BCD u otra clase decimal que no tenga la deficiencia de representación IEEE754.

¿Qué tal esto para otra posible solución:

 printf("%.2f", _nextafter(n, n*2)); 

La idea es boost el número lejos de cero (el n * 2 tiene el signo correcto) en la cantidad más pequeña posible representada por las matemáticas de coma flotante.

P.ej:

 double n=5.555; printf("%.2f\n", n); printf("%.2f\n", _nextafter(n, n*2)); printf("%.20f\n", n); printf("%.20f\n", _nextafter(n, n*2)); 

Con los rendimientos de MSVC:

 5.55 5.56 5.55499999999999970000 5.55500000000000060000 

Esta pregunta está etiquetada como C ++, por lo que procederé bajo esa suposición. Tenga en cuenta que las secuencias de C ++ se redondearán, a diferencia de la familia de C printf. Todo lo que tiene que hacer es proporcionar la precisión que desea y la biblioteca de flujos se redondeará para usted. Solo lo estoy tirando por ahí en caso de que no tengas una razón para no usar streams.

También puedes hacer esto (guarda multiplicar / dividir):

 printf("%.2f\n", coef[i] + 0.00049999);