#c_sharp #cpp #python #c
Хотелось бы узнать как правильно найти минимальное целое число не представимое в float и десятичной арифметике с заданной мантиссой и экспонентами(минимальная,максимальная)
Ответы
Ответ 1
В С константы FLT_MANT_DIG DBL_MANT_DIG LDBL_MANT_DIG издадут вам количество цифр в мантиссе соответствующего плавающего типа. Каждая цифра мантиссы - в базе FLT_RADIX (обычно 2). В С++ те же значения можно также получить через std::numeric_limits ::digits. Соответственно, все целые числа, чей модуль не превосходит 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 #include #include int main() { static_assert(FLT_RADIX == 2, "Ya krevedko"); { unsigned long long i = 1ull << FLT_MANT_DIG; float f = i; printf("%llu %f\n", i, f); f = ++i; printf("%llu %f\n", i, f); } { unsigned long long i = 1ull << DBL_MANT_DIG; double f = i; printf("%llu %lf\n", i, f); f = ++i; printf("%llu %lf\n", 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 будут представляться уже только четные целые числа. Но на вышеприведенные рассуждения это не оказывает принципиального влияния. Принципиальный момент тут в любом случае один и тот же - непрерывный диапазон целых чисел определяется шириной мантиссы.
Комментариев нет:
Отправить комментарий