#c#
#c#
Вопрос:
Я обновил программу расчета и обнаружил, что результаты неожиданно изменились. Я обнаружил проблему, но понятия не имею, как это может произойти и как ее решить.
Разница в результате вызвана этим утверждением
Convert.ToDouble(0.0000000035141287671294348266M)
Когда я открываю два экземпляра Visual Studio Community 2015 для запуска как новой, так и старой программы, устанавливаю точку останова перед инструкцией и оцениваю ее в немедленном окне, я могу получить два результата.
Один из них
3.514128767129435E-09
а другой —
3.5141287671294345E-09
Кажется, что первое верно (4348266 округлено до 435), но если я прерву предыдущую программу сразу после ее запуска и снова выполню оценку, результатом станет последнее.
Это не огромная разница, но поведение меня пугает. Какой из них должен быть правильным результатом? Как я могу избежать проблемы?
Комментарии:
1. Когда вы говорите «обновлено», что вы имеете в виду? Что изменилось между двумя версиями?
2. Пользовательский интерфейс, рефакторинг и т.д. Многое было изменено. Старая программа была разработана в VS2010 и перекомпилирована в VS2015. Используется тот же .NET framework 4.0.
3. Версия VS не имеет ничего общего с фактической средой выполнения и предоставленными библиотеками. Если . Версия NET framework не изменилась, не должно быть никакого влияния на реализацию. В общем случае, когда вы усекаете a
decimal
до adouble
, вы теряете точность, именно поэтому вы должны использоватьdecimal
, если это важно для вас. Если точность не гарантируется для 16-й цифры, вы не можете ничего предполагать по этому поводу.4. нет, когда вы представляете число как double, оно может быть представлено различными способами, поэтому вы не можете быть уверены, что одна и та же операция может обеспечить точно такие же значения, когда речь идет о точности. Значения могут быть близкими, но не всегда совпадать с последними цифрами
5. @lya Это именно то, что связано с неопределенным поведением, оно не определено .
Ответ №1:
Проблема заключается в том, какова на самом деле гарантированная точность double.
Согласно MSDN, это 15-16 цифр, а что касается вашего примера, разница видна только на 16-й цифре.
Комментарии:
1. Да, я уже проверял эту страницу MSDN раньше. Но разве это не должно давать одинаковые результаты в одной и той же версии VS для одного и того же оператора, независимо от того, какова точность?
2. Как уже говорилось, точность составляет 15 или 16 цифр. В одном случае это 15 цифр (правильно округленных до 435 в конце), в другом случае это 16 цифр (округленных до 4345 в конце). Таким образом, было бы безопасно предположить, что никогда не ожидайте точности более 15 цифр с удвоением.