Почему форматирование Double с использованием строки стандартного формата G не возвращает полную строку?

Я надеюсь, что изучил это достаточно, чтобы моя предпосылка не была полностью ошибочной. Если это так, то математики могут меня поправить.

Я предполагаю, что значение Double, такое как 12.5, должно быть округлено до 5 значащих цифр (НЕ десятичных знаков), как 12.500. Вместо этого, используя следующий код C#, я получаю 12.5:

Double d = 12.5;
Console.WriteLine(d.ToString("G5"));

Я наткнулся на этот пост от 2007 года. который, кажется, повторяет мою проблему. На самом деле, я использую эти номера примеров только для того, чтобы все было согласовано.

Моя цель здесь состоит в том, чтобы лучше понять следующее:

  • Правильно ли мое понимание sig figs математически? То есть, разумно ли мое ожидание, или вывод «12,5» как-то верен?

  • Это действительно (очень долгоживущая) ошибка в фреймворке? Если да, то можно/будет ли это исправлено?

  • Предполагая, что это ошибка, что я могу сделать с этим сейчас? Написать хак, чтобы определить, сколько sig figs вы фактически вернули, а затем дополнить его? Свернуть мой собственный код, чтобы сделать то, что должна была делать строка формата "G"? Я уже сталкивался с примерами этого на SO, так что, возможно, это свидетельствует о том, что чистого варианта не существует.

Кроме того, я понимаю, что проблемы с хранением Double могут негативно повлиять на аспект округления этой проблемы, но на данный момент меня интересует только вопрос о большем количестве цифр, чем исходных цифр.

РЕДАКТИРОВАТЬ: я тестировал это до версии 4.5.


person DonBoitnott    schedule 01.12.2014    source источник
comment
Значение 12,5 имеет только 3 значащие цифры. Точность указывает максимальное количество цифр в выводе, а не точное количество цифр. Замечу, что я отвечал в той ветке, на которую вы ссылаетесь, примерно теми же мыслями, что и здесь...   -  person Jon Skeet    schedule 01.12.2014
comment
@JonSkeet Это говорит о максимуме. Это ускользнуло от меня при первом прочтении. Тем не менее, меня беспокоит ответ Бена Фойгта, который предположил, что 12 500 будет более точным математически, поскольку он предполагает большую точность для читателя. Разве это не правда? Именно это предположение о точности я и пытаюсь передать.   -  person DonBoitnott    schedule 01.12.2014
comment
Хотя я понимаю вашу точку зрения, я думаю, что документация, которую цитирует Рик, является наиболее убедительной, если честно. Если вас интересует определенное количество значащих цифр, включая конечные нули, вам может понадобиться посмотреть decimal.   -  person Jon Skeet    schedule 01.12.2014


Ответы (2)


См. эту ссылку в спецификатор G-формата. В нем четко сказано:

Результат содержит десятичную точку, если требуется, а конечные нули после десятичной точки опускаются.

person Rick Davin    schedule 01.12.2014

Значение Double округляется до 15 значащих цифр, а не до пяти.

Ссылка: Общие ("G") спецификатор формата

Округление числа до любого количества значащих цифр не означает, что отформатированная строка должна содержать это количество цифр. Если значение округляется до 12.5000000000000, оно будет отформатировано до "12.5", поскольку это наиболее компактный способ представления значения.

person Guffa    schedule 01.12.2014
comment
Я понимаю разницу между круглыми и значащими цифрами. Я предполагаю, что 12,500 передает читателю большую точность значения, чем 12,5. И моя память об определении sig figs коррелирует с этим. Теперь строки форматирования С# могут работать не очень хорошо... - person DonBoitnott; 01.12.2014
comment
@DonBoitnott: тип данных Double не отслеживает предысторию значения, поэтому для отображения полной точности он всегда будет отформатирован до 15 значащих цифр. Если вы присвоите переменной 12.500, она все равно будет отформатирована в 12.5000000000000, потому что это точность, с которой может работать тип данных, даже если ввод не был таким точным. - person Guffa; 02.12.2014