Найти мин / макс с плавающей / двойной, который имеет такое же внутреннее представление
Обновление наплавающие точки (такжеPDF), IEEE-754 и участиев этом обсуждении округления с плавающей запятой при преобразовании в строки, привел меня к возиться: как я могу получить максимальное и минимальное значение для данного числа с плавающей запятой, двоичные представления которого равны.
отказ: для этого обсуждения мне нравится придерживаться 32-битной и 64-битной плавающей запятой, как описано в IEEE-754. Я'меня не интересуют расширенные числа с плавающей запятой (80 бит) или квадраты (128 бит IEEE-754-2008) или любой другой стандарт (IEEE-854).
Фон: Компьютеры плохо представляют0.1
в двоичном представлении. В C # поплавок представляет это как3DCCCCCD
внутренне (C # использует округление до ближайшего) и двойной как3FB999999999999A
, Те же самые битовые комбинации используются для десятичной0.100000005
(плавать) и0.1000000000000000124
(двойной), но не для0.1000000000000000144
(Дважды).
Для удобства следующий код C # дает эти внутренние представления:
string GetHex(float f)
{
return BitConverter.ToUInt32(BitConverter.GetBytes(f), 0).ToString("X");
}
string GetHex(double d)
{
return BitConverter.ToUInt64(BitConverter.GetBytes(d), 0).ToString("X");
}
// float
Console.WriteLine(GetHex(0.1F));
// double
Console.WriteLine(GetHex(0.1));
В случае0.1
, не существует нижнего десятичного числа, представленного одинаковым битовым шаблоном,0.99...99
даст другое представление битов (то есть, float для0.999999937
доходность3F7FFFFF
внутри).
Мой вопрос прост: как найти наименьшее и наибольшее десятичное значение для данного числа с плавающей запятой (или двойного), которое внутренне хранится в том же двоичном представлении.
Зачем: (Я тебя знаю'Я попрошу) найти ошибку при округлении в .NET, когда она преобразуется в строку, и когда она преобразуется из строки, чтобы найти точное внутреннее значение и лучше понять свои ошибки округления.
Я думаю, что-то вроде: взять мантиссу, удалить остальные, получить его точное значение, получить на один (бит мантиссы) выше и вычислить среднее значение: все, что ниже, даст тот же битовый шаблон. Моя главная проблема: как получить дробную часть как целое число (манипулирование битами это не мой самый сильный актив).Джон Скитс DoubleConverter класс может быть полезным.