Какой диапазон чисел может быть представлен в 16-, 32- и 64-битных системах IEEE-754?

Я немного знаю о том, как представлены числа с плавающей точкой, но, боюсь, этого недостаточно.

Общий вопрос:

Какой диапазон чисел может быть представлен для 16-, 32- и 64-битных систем IEEE-754 для заданной точности (для моих целей, количества точных десятичных знаков в базе 10)?

В частности, меня интересует только диапазон 16-битных и 32-битных чисел с точностью до +/-0,5 (одно место) или +/-0,0005 (тысячное место).

7 ответов

Решение

Я черпаю этот ответ из документации MATLAB для функции EPS, но он должен применяться повсеместно к числам с плавающей запятой IEEE-754.

Для заданного числа с плавающей запятой X, если

2^E <= abs(X) < 2^(E+1)

тогда расстояние от X до следующего наибольшего представимого числа с плавающей точкой (эпсилон) равно:

epsilon = 2^(E-52)    % For a 64-bit float (double precision)
epsilon = 2^(E-23)    % For a 32-bit float (single precision)
epsilon = 2^(E-10)    % For a 16-bit float (half precision)

Приведенные выше уравнения позволяют нам вычислить следующее:

  • Для полу точности...

    Если вы хотите получить точность +/-0,5 (или 2^-1), максимальный размер, которым может быть это число, составляет 2^10. Любое значение больше этого, а расстояние между числами с плавающей точкой больше 0,5.

    Если вам нужна точность +/-0,0005 (примерно 2^-11), максимальный размер, который может быть числом, равен 1. Любое значение больше этого, а расстояние между числами с плавающей запятой больше 0,0005.

  • Для одинарной точности...

    Если вам нужна точность +/-0,5 (или 2^-1), максимальный размер, которым может быть это число, составляет 2^23. Любое значение больше этого, а расстояние между числами с плавающей точкой больше 0,5.

    Если вы хотите получить точность +/-0,0005 (около 2^-11), максимальный размер, который может быть указан, равен 2^13. Любое значение больше этого, а расстояние между числами с плавающей точкой больше 0,0005.

  • Для двойной точности...

    Если вам нужна точность +/-0,5 (или 2^-1), максимальный размер, которым может быть число, составляет 2^52. Любое значение больше этого, а расстояние между числами с плавающей точкой больше 0,5.

    Если вы хотите получить точность +/-0,0005 (около 2^-11), максимальный размер, который может быть указан, равен 2^42. Любое значение больше этого, а расстояние между числами с плавающей точкой больше 0,0005.

Для целых чисел с плавающей точкой (я дам свой ответ в терминах двойной точности IEEE), каждое целое число от 1 до 2^53 является точно представимым. За пределами 2^53 целые числа, которые точно представимы, разнесены с помощью увеличения степеней в два. Например:

  • Каждое второе целое число от 2^53 + 2 до 2^54 может быть представлено точно.
  • Каждое четвертое целое число от 2^54 + 4 до 2 ^ 55 может быть представлено точно.
  • Каждое восьмое целое число от 2^55 + 8 до 2 ^ 56 может быть представлено точно.
  • Каждое шестнадцатое целое число от 2^56 + 16 до 2^57 может быть представлено точно.
  • Каждое 32-е целое число от 2^57 + 32 до 2^58 может быть представлено точно.
  • Каждое 64-е целое число от 2^58 + 64 до 2^59 может быть представлено точно.
  • Каждое 128-е целое число от 2^59 + 128 до 2^60 может быть представлено точно.
  • Каждое 256-е целое число от 2^60 + 256 до 2^61 может быть представлено точно.
  • Каждое 512-е целое число от 2^61 + 512 до 2 ^ 62 может быть представлено точно.,,,

Целые числа, которые не являются точно представимыми, округляются до ближайшего представимого целого числа, поэтому в худшем случае округление составляет 1/2 расстояния между представимыми целыми числами.

Точность цитирования из ссылки Питера Р. на ссылку MSDN, вероятно, является хорошим практическим правилом, но, конечно, реальность сложнее.

Тот факт, что "точка" в "плавающей точке" является бинарной, а не десятичной точкой, может побеждать нашу интуицию. Классическим примером является 0.1, который требует точности только одной цифры в десятичном формате, но не представляется точно в двоичном виде.

Если у вас есть выходные, чтобы убить, взгляните на то, что каждый компьютерщик должен знать об арифметике с плавающей точкой. Вы, вероятно, будете особенно заинтересованы в разделах о точности и двоичном в десятичное преобразование.

Во-первых, ни IEEE-754-2008, ни -1985 не имеют 16-битных чисел с плавающей запятой; но это предлагаемое дополнение с 5-битным показателем и 10-битной дробью. IEE-754 использует специальный бит знака, поэтому положительный и отрицательный диапазоны одинаковы. Кроме того, фракция имеет подразумеваемую 1 впереди, так что вы получите дополнительный бит.

Если вам нужна точность в тех местах, где вы можете представить каждое целое число, ответ довольно прост: экспонента смещает десятичную точку в правый конец дроби. Итак, 10-битная дробь дает вам ± 211.

Если вы хотите один бит после десятичной запятой, вы отказываетесь от одного бита перед ним, поэтому у вас есть ± 210.

Одинарная точность имеет 23-битную дробь, поэтому у вас будет ± 224 целых числа.

Сколько бит точности вам нужно после десятичной запятой полностью зависит от вычислений, которые вы делаете, и от того, сколько вы делаете.

  • 210 = 1024
  • 211 = 2048
  • 223 = 8 388 608
  • 224 = 16 777 216
  • 253 = 9 007 199 254 740 992 (с двойной точностью)
  • 2113 = 10 384 593 717 069 655 257 060 992 658 440 192 (с четверной точностью)

Смотрите также

См. IEEE 754-1985:

v = (-1) ^ знак * с ^ (экспонента-экспонента_без) * (1 + дробь)

Примечание (1 + дробь). Как указывает @bendin, используя двоичные числа с плавающей запятой, вы не можете выразить простые десятичные значения, такие как 0,1. Подразумевается, что вы можете вводить ошибки округления, выполняя простые добавления много раз или вызывая такие вещи, как усечение. Если вас интересует какая-либо точность, единственный способ достичь ее - использовать десятичную с фиксированной запятой, которая в основном представляет собой масштабированное целое число.

Если я правильно понимаю ваш вопрос, это зависит от вашего языка.
Для C# проверьте MSDN ref. Float имеет точность 7 цифр и двойную точность 15-16 цифр.

Мне потребовалось много времени, чтобы понять, что при использовании double в Java я не теряю значительную точность вычислений. на самом деле с плавающей точкой очень хорошая способность представлять числа с достаточно разумной точностью. Я терял точность сразу после преобразования десятичных чисел, набранных пользователями, в двоичное представление с плавающей запятой, которое изначально поддерживается. Я недавно начал конвертировать все свои числа в BigDecimal. BigDecimal - это гораздо больше работы в коде, чем числа с плавающей запятой или двойные числа, поскольку это не один из примитивных типов. Но с другой стороны, я смогу точно представлять цифры, которые вводят пользователи.

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