. NET В ядре появилось множество синтаксического анализа и форматирования с плавающей запятой улучшений в соответствии IEEE с плавающей запятой. Одним из них является соответствие форматированию IEEE 754-2008.
До. NET Core 3.0, ToString()
внутренне ограниченная точность до "всего лишь" 15 мест, в результате чего получается строка, которая не может быть проанализирована обратно к оригиналу , Значения вопроса отличаются на один бит .
В обоих. NET 4.7 и. NET Core 3, фактические байты остаются теми же. В обоих случаях вызов
BitConverter.GetBytes(d*d*d)
производит
85, 14, 45, 178, 157, 111, 27, 64
С другой стороны, BitConverter.GetBytes(6.859)
производит:
86, 14, 45, 178, 157, 111, 27, 64
Даже в. NET Core 3, синтаксический анализ "6.859" создает вторую последовательность байтов:
BitConverter.GetBytes(double.Parse("6.859"))
Это разница в один бит. Старое поведение приводило к строке, которая не могла быть проанализирована обратно к исходному значению
Разница объясняется этим изменением:
ToString (), ToString ("G") и ToString ("R") теперь будет возвращать самую короткую строку для переворачивания. Это гарантирует, что пользователи получат что-то, что просто работает по умолчанию.
Вот почему нам всегда нужно указывать точность при работе с числами с плавающей запятой. В этом случае также были улучшения:
Для спецификатора формата "G", который принимает точность (например, G3), спецификатор точности теперь всегда учитывается. Для double с точностью менее 15 (включительно) и для float с точностью менее 6 (включительно) это означает, что вы получите ту же строку, что и раньше. Для точности, превышающей это, вы получите до стольких значащих цифр
Использование ToString("G15")
дает 6.859
, тогда как ToString("G16")
дает 6.858999999999999
, который имеет 16 дробных цифр.
Это напоминание о том, что нам всегда нужно указывать точность при работе с числами с плавающей запятой, будь то сравнение или форматирование