Pregunta

Assert.Equal(1000000.0, table.Convert("g", "mcg", 1.0)); // Pass
Assert.Equal(2000000.0, table.Convert("g", "mcg", 2.0)); // Pass
Assert.Equal(3200000.0, table.Convert("g", "mcg", 3.2)); // Fail
// The failing one is equal to doing the following calculation, which fails also:
Assert.Equal(3200000.0, 3.2 * 1.0 / (1.0 / 1000000.0));  // Fail
Assert.Equal(3200000.0, 3.2 * (1.0 / (1.0 / 1000000.0)));// Pass, WTF?!?!
===================================================================    
Assert.Equal() Failure
    Expected: 3200000
    Actual:   3200000
¿Fue útil?

Solución

Con la diferente orden de las operaciones, el binario de coma flotante aparecen errores de redondeo que se propaga de manera diferente. Usted puede conseguir "menos sorprendentes", pero potencialmente más lentos resultados con el tipo Decimal.

3,2 * 1,0 / (1,0 / 1000000.0) -> 3,200,000.0000000005

(try (3.2 * 1.0 / (1.0 / 1000000.0) ).ToString("R");

3,2 * (1,0 / (1,0 / 1000000.0)) -> 3200000.0

Si usted no tiene ya entender las diferencias entre los tipos de punto decimal flotante y, por favor, lea: http://docs.sun.com/source/806-3568/ncg_goldberg.html

O, si se prefiere algo más claro en Inglés: http://floating-point-gui.de/

Otros consejos

Yoe no puede verlo desde el fragmento de código, pero estoy bastante seguro de que tiene algo que ver con el hecho de que sus primeras líneas (los que pasan a) tener un .0, mientras que el fallido tiene algo desigual a cero después de la coma.

Estoy seguro de que hay algo extraño como 3.2000000001 venir en alguna parte. Tal vez a partir de la base de datos?

HTH
Thomas

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top