Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > диапазон целых чисел в double без потери точности


Автор: leniviy 25.9.2012, 12:02
Подскажите непрерывный диапазон целых чисел, которые можно хранить в переменной типа double без потери точности.
Это точно не DBL_MIN..DBL_MAX
Код

#include <stdio.h>
#include <float.h>
int main() {
  double d1 = DBL_MAX;
  double d2 = d1 - 1;
  printf("%d\n", d1 == d2);
  return 0;
}

Код

1

Автор: Alexeis 25.9.2012, 12:16
-/+ 4 503 599 627 370 496

__int64 может больше.

Автор: tzirechnoy 26.9.2012, 11:23
Да, примерно +-2^[число бит мантиссы-1], кстати. На будущее.

Автор: Alexeis 26.9.2012, 14:00
 А почему -1 ? В числах с плавающей точкой знак хранится отдельно. 

Автор: math64 27.9.2012, 08:27
Код

double f = 1;
int n = 0;
for(;;) {
  n++;
  f = f * 2;
  double f1 = f + 1;
  double f2 = f + 2;
  if (f == f1 || f1 == f2) break;
}
printf ("%d %17g\n", n, f);

Мантисса позволяет хранить целые от 0 до 2^n-1, но за счёт экспоненты double может хранить и 2^n. За счёт того, что знак хранится отдельно, диапазон симметричен -2^n ... 2^n

Автор: tzirechnoy 27.9.2012, 18:32
Цитата
 А почему -1 ? В числах с плавающей точкой знак хранится отдельно. 


Ну, по факту -- если там один бит, то только 0, +1, -1. 2 ужэ от 3 не отличить. То есть +-2^0.

PS Да, я в биты включал и неявный, если он есть. В IEEE 754 double -- есть (малые числа не рассматриваем за нерелевантностью), т.е. 53 бита мантиссы записываются в 52 бита в памяти.

Автор: Alexeis 28.9.2012, 10:05
Цитата(tzirechnoy @  27.9.2012,  19:32 Найти цитируемый пост)
Ну, по факту -- если там один бит, то только 0, +1, -1. 2 ужэ от 3 не отличить. То есть +-2^0.

  Все равно не верно. Тогда можно сказать лишь, что (2^n) - 1, а не 2^(n-1)

  Возьмем число в основном коде состоящее из 3х бит 111 (бинарная система) = 7 (десятичная)
2^(3-1) = 4
(2^3) - 1 = 7


Автор: math64 28.9.2012, 10:13
Цитата(Alexeis @  28.9.2012,  10:05 Найти цитируемый пост)
 Все равно не верно. Тогда можно сказать лишь, что (2^n) - 1, а не 2^(n-1)

  Возьмем число в основном коде состоящее из 3х бит 111 (бинарная система) = 7 (десятичная)
2^(3-1) = 4
(2^3) - 1 = 7

8 тоже записывается в виде 100(2)*10(2)^1
А 9 уже нет, при выолнении 8+1 можно получить 8 или 10 (в зависимости от правил округления)
Поэтому при 3 битах мантиссы (1 из них может быть скрытым) диапазон будет -8...8, т. е. -2^n...2^n без всяких -1

Автор: tzirechnoy 28.9.2012, 14:11
Цитата
 Возьмем число в основном коде состоящее из 3х бит 111 (бинарная система) = 7 (десятичная)
2^(3-1) = 4
(2^3) - 1 = 7


(хар)0xy == (хар-1)xy0. Так что выкидываем как дубли 001, 010, 011 (000 -- симметричен и не дублируется). То есть остаётся +-4. Доказывать -- лень (оставляю это для самостоятельной тренировки smile)

Добавлено через 1 минуту и 36 секунд
А можэт, и не выкидываем. Чёрт, думать надо. Но по-моему выкидываем. Вечером подумаю.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)