Когда я выполняю эту строку:
double dParsed = double.Parse("0.00000002036");
dParsed на самом деле получает значение: 0.000000020360000000000002
По сравнению с этой строкой
double dInitialized = 0.00000002036;
в этом случае значение dInitialized равно 0,00000002036.
Вот они в отладчике:
Это несоответствие немного раздражает, потому что я хочу запускать тесты следующим образом:
[Subject("parsing doubles")]
public class when_parsing_crazy_doubles
{
static double dInitialized = 0.00000002036;
static double dParsed;
Because of = () => dParsed = double.Parse("0.00000002036");
It should_match = () => dParsed.ShouldBeLike(dInitialized);
}
Это, конечно, терпит неудачу с:
Machine.Specifications.SpecificationException "": Expected: [2.036E-08] But was: [2.036E-08]
В моем производственном коде «проанализированные» двойники считываются из файла данных, тогда как значения сравнения жестко запрограммированы как инициализаторы объектов. Из многих сотен записей 4 или 5 из них не совпадают. Исходные данные отображаются в текстовом файле следующим образом:
0.00000002036 0.90908165072 6256.77753019160
Таким образом, анализируемые значения имеют только 11 знаков после запятой. Есть идеи, как обойти это несоответствие?
Хотя я согласен с тем, что сравнивать двойные числа на равенство рискованно, я удивлен, что компилятор может получить точное представление, когда текст используется в качестве инициализатора объекта, но этот double.Parse не может получить точное представление при разборе точно такого же текст. Как я могу ограничить анализируемые двойники до 11 знаков после запятой?
0.00000002036
is really 2.035999999999999834810563976821018439267163557815365493297576904296875e-08 and0.000000020360000000000002
is really 2.0360000000000001656828089980320883878306403858005069196224212646484375e-08. Разница между ними ровно 2^(-78). - person dan04   schedule 31.01.2014