Разве double не может представить любое число 2^n без проблем точности? п естественно

Этот код:

double x = 2.0;
for(int i = 1 ; i<1024 ; i+=i) {
    Console.WriteLine( String.Format( "2^{0} = {1:F0}", i, x ) );
    x*=x;
}

Выходы:

2^1 = 2
2^2 = 4
2^4 = 16
2^8 = 256
2^16 = 65536
2^32 = 4294967296
2^64 = 18446744073709600000
2^128 = 340282366920938000000000000000000000000
2^256 = 115792089237316000000000000000000000000000000000000000000000000000000000000000
2^512 = 13407807929942600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Я думал, что формула двойника sign * 2 ^ exponent * fraction; Проиллюстрировать мою ситуацию; С настройкой fraction в 0.5, знак к положительному, и путем установки exponent к любому значению между -1024 в 1023Я могу представить любой 2^n номер, который находится в exponentассортимент; Что не так с этим выводом? Является ли формула неполной?

4 ответа

Решение

double может представлять степени 2 точно, как показано в следующем коде (который использует Jon Skeet's DoubleConverter учебный класс):

Console.WriteLine(String.Format("2^{0} = {1}", i, DoubleConverter.ToExactString(x)));

Для спецификатора F0, почему разработчики.NET решили округлить значение после 15 наиболее значимых десятичных цифр?

Мое предположение: отображение точного значения (например, 18446744073709551616) может означать, что double является точным для всех этих цифр, когда на самом деле double не может различить это значение и 18446744073709600000. Кроме того, отображение округленного значения согласуется с экспоненциальной нотацией: 1.84467440737096E+19.

Ответ на ваш вопрос заключается в том, что число с двойной точностью IEEE 754 является 64-битным значением:

  • 1 бит это знак
  • 11 бит представляют показатель степени
  • 52 бита представляют значение (но из-за немного глубокой магии, знак действительно имеет 53 бита точности).

Он может представлять не более 2 64 дискретных значений - так же, как 64-разрядное целое число (и на самом деле меньше из-за таких вещей, как NaN, положительный и отрицательный ноль и т. д.)

Его диапазон, однако, намного больше, чем у 64-битного целого числа: он может представлять десятичные значения примерно от 10 -308 до 10 +308... хотя и с точностью не более 15-17 десятичных цифр.

С плавающей точкой меняет точность на диапазон. Это компромисс.

См. Бинарный формат с плавающей запятой IEEE-754 двойной точности для более подробной информации.

Более того, прочитайте статью Дэвида Голдберга 1991 года "Что должен знать каждый компьютерщик об арифметике с плавающей точкой":

Аннотация. Арифметика с плавающей точкой рассматривается многими людьми как эзотерический предмет. Это довольно удивительно, потому что с плавающей точкой в ​​компьютерных системах повсеместно: почти каждый язык имеет тип данных с плавающей точкой; компьютеры от ПК до суперкомпьютеров имеют ускорители с плавающей запятой; большинство компиляторов будут время от времени компилировать алгоритмы с плавающей точкой; и практически каждая операционная система должна реагировать на исключения с плавающей точкой, такие как переполнение. Эта статья представляет учебное пособие по аспектам с плавающей запятой, которые оказывают непосредственное влияние на разработчиков компьютерных систем. Он начинается с предыстории представления с плавающей запятой и ошибки округления, продолжается обсуждением стандарта IEEE с плавающей запятой и заканчивается примерами того, как сборщики компьютерных систем могут лучше поддерживать с плавающей запятой.

Дэвид Голдберг. 1991. "Что должен знать каждый компьютерщик об арифметике с плавающей точкой". ACM Comput. Surv. 23, 1 (март 1991), 5-48. DOI = 10.1145 / 103162.103163 http://doi.acm.org/10.1145/103162.103163

http://msdn.microsoft.com/en-us/library/678hzkk9.aspx

Ключевое слово double обозначает простой тип, в котором хранятся 64-битные значения с плавающей точкой. В следующей таблице показана точность и приблизительный диапазон для типа double.

Type
double

Approximate range
±5.0 × 10−324 to ±1.7 × 10308

Precision
15-16 digits

Нет. Ваш аргумент терпит неудачу в "путем установки показателя в любое значение".

Есть ограниченный диапазон exponentВы не можете представлять

pow(2, 1000000)

хотя 1000000 натуральное число.

Другие вопросы по тегам