Хотя этот вопрос пока закрыт, я считаю, что стоит упомянуть, как возникло это злодеяние. В некотором смысле вы можете обвинить спецификацию C #, которая гласит, что double должен иметь точность 15 или 16 цифр (результат IEEE-754). Чуть дальше (раздел 4.1.6) указано, что реализациям разрешено использовать более высокую точность. Имейте в виду: выше , не ниже. Им даже разрешается отклоняться от IEEE-754: выражения типа x * y / z
, где x * y
будет давать +/-INF
, но будут находиться в допустимом диапазоне после деления, не должны приводить к ошибке. Эта функция позволяет компиляторам использовать более высокую точность в архитектурах, где это приведет к повышению производительности.
Но я обещал "причину". Вот цитата (вы запросили ресурс в одном из ваших последних комментариев) из CLI Shared Source *1011*:
"Чтобы дать числа, которые оба
дружественный для отображения и
Мы можем разобрать число
используя 15 цифр, а затем определить, если
это поездки туда и обратно к одному и тому же значению. Если
это делает, мы конвертируем это число в
строка, в противном случае мы обрабатываем 17
цифры и отобразите это. "
Другими словами: команда разработчиков CLI MS решила быть способной к быстрому обращению и показывать симпатичные значения, которые не так уж трудно читать. Хорошо или плохо? Я хотел бы подписаться или отказаться.
Хитрость, которую нужно сделать, чтобы выяснить эту возможность округления любого числа? Преобразование в общую структуру NUMBER (которая имеет отдельные поля для свойств типа double) и обратно, а затем сравните, отличается ли результат. Если оно отличается, используется точное значение (как в среднем значении с 6.9 - i
), если оно одинаковое, используется «симпатичное значение».
Как вы уже отметили в комментарии к Andyp, 6.90...00
поразрядно равен 6.89...9467
. И теперь вы знаете, почему используется 0.0...8818
: он поразрядно отличается от 0.0
.
Этот 15-значный барьер жестко запрограммирован и может быть изменен только путем перекомпиляции CLI, использования Mono или вызова Microsoft и убеждения их добавить опцию для печати полной «точности» (это не совсем точно, но из-за отсутствия лучшего слова). Вероятно, проще просто вычислить 52-битную точность самостоятельно или использовать библиотеку, упомянутую ранее.
РЕДАКТИРОВАТЬ: если вы хотите поэкспериментировать с плавающей точкой IEE-754, рассмотрите этот онлайн-инструмент , который показывает вам все соответствующие части с плавающей запятой.