Хотелось бы узнать как правильно найти минимальное целое число не представимое в float и десятичной арифметике с заданной мантиссой и экспонентами(минимальная,максимальная)
Ответ
В С константы
FLT_MANT_DIG
DBL_MANT_DIG
LDBL_MANT_DIG
из
Соответственно, все целые числа, чей модуль не превосходит FLT_RADIXFLT_MANT_DIG должны быть представимы. А вот
FLT_RADIXFLT_MANT_DIG + 1
будет первым (минимальным) положительным целым не представимым в типе float
Почему так? Так устроены плавающие типы. Если убрать не относящиеся к делу детали, то плавающее двоичное значение представляется по принципу
значение = мантисса * 2экспонента
Если полагать, что мантисса - целое число(1, то при любом значении экспоненты больше 0, в последовательности представимых таким способом целых чисел будут "дырки". Например, очевидно, что при экспоненте 1 представимы будут только четные числа. Непрерывная последовательность целых чисел возможна только при нулевой величине экспоненты, а также в точке перехода от экспоненты 0 к экспоненте 1.
Для экспоненты 0 диапазон ограничен диапазоном значений самой мантиссы. В типе float ширина мантиссы - 24 (это FLT_MANT_DIG). Соответственно диапазон представимых целых идет от 0 до 224-1. А затем, при переходе к экспоненте 1 мы получаем еще одно представимое целое число: 224. А вот следующим представимым целым числом при экспоненте 1 будет только 224+2. Так что число 224+1 - это первая "дырка" в последовательности представимых целых чисел.
Проверим
#include
int main()
{
static_assert(FLT_RADIX == 2, "Ya krevedko");
{
unsigned long long i = 1ull << FLT_MANT_DIG;
float f = i;
printf("%llu %f
", i, f);
f = ++i;
printf("%llu %f
", i, f);
}
{
unsigned long long i = 1ull << DBL_MANT_DIG;
double f = i;
printf("%llu %lf
", i, f);
f = ++i;
printf("%llu %lf
", i, f);
}
}
Вывод
16777216 16777216.000000
16777217 16777216.000000
9007199254740992 9007199254740992.000000
9007199254740993 9007199254740992.000000
Таким образом в IEEE 754 типа float первое непредставимое целое число - это 16777217, а для типа double - это число 9007199254740993
Та же формула применима и к десятичным представлениям с плавающей точкой, построенным на тех же принципах.
1) В реальности в IEEE 754 все несколько по-другому. Мантисса - это двоичное число с точкой вида 1.000...0 шириной в 24 бита (т.е. 23 двоичных знака после точки), и соответственно идущие подряд целые числа будут представляться при значениях экспоненты до 23. А начиная со значения экспоненты 24 будут представляться уже только четные целые числа. Но на вышеприведенные рассуждения это не оказывает принципиального влияния. Принципиальный момент тут в любом случае один и тот же - непрерывный диапазон целых чисел определяется шириной мантиссы.
Комментариев нет:
Отправить комментарий