Сколько двузначных чисел между 0.0 и 1.0?
Это то, что было у меня на уме в течение многих лет, но я никогда не взял время, чтобы спросить, прежде чем.
много (псевдо) генераторы случайных чисел, генерируют случайное число между 0.0 и 1.0. Математически есть бесконечные числа в этом диапазоне, но double является числом с плавающей запятой, и поэтому имеет конечную точность.
поэтому вопросы:
- сколько
doubleчисло между 0.0 и 1.0? - там так же много чисел между 1 и 2? Между 100 и 101? Между 10^100 и 10^100+1?
Примечание: если это имеет значение, я заинтересован в определении Java double в частности.
6 ответов:
Java
doubles находятся в IEEE-754 формат, поэтому они имеют 52-битную дробь; между любыми двумя смежными степенями двух (включая одну и исключая следующую), поэтому будет 2 до 52-й степени, отличнойdoubles (т. е. 4503599627370496 из них). Например, это число различныхdoubleмежду 0.5 и 1.0 включенными основе, а именно, что многие так же лежат между 1.0 и 2.0 включены основе, и так далее.подсчет элемент
doublesмежду 0.0 и 1.0 сложнее, чем делать это между степенями двух, потому что есть много степеней двух, включенных в этот диапазон, а также один попадает в острые вопросы денормализованных чисел. 10 из 11 битов экспонент охватывают рассматриваемый диапазон, поэтому, включая денормализованные числа (и я думаю, что несколько видовNaN) у вас было бы 1024 разаdoubles как лежал между степенями двух -- не более чем2**62в общем так или иначе. Кроме ненормированные &c, я считаю счет будет 1023 раза2**52.для произвольного диапазона, такого как" 100 до 100.1", это еще сложнее, потому что верхняя граница не может быть точно представлена как
double(не является точным кратным любой степени из двух). В качестве удобного приближения, поскольку прогрессия между степенями двух является линейной, вы можете сказать, что указанный диапазон0.1 / 64th промежутка между окружающими силами двух (64 и 128), так что вы ожидаете около(0.1 / 64) * 2**52distinct
doubles -- который приходит к7036874417766.4004... плюс-минус один или два;-).
doubleзначение, представление которого находится между0x0000000000000000и0x3ff0000000000000лежит в интервале [0.0, 1.0]. Это (2^62 - 2^52) различные значения (плюс или минус пара в зависимости от того, считаете ли вы конечные точки).интервал [1.0, 2.0] соответствует представлениям между
0x3ff0000000000000и0x400000000000000; это 2^52 различных значений.интервал [100.0, 101.0] соответствует представлениям между
0x4059000000000000и0x4059400000000000; это 2^46 различных ценности.нет двойников между 10^100 и 10^100 + 1. Ни одно из этих чисел не представляется с двойной точностью, и между ними нет двойников. Ближайшие два числа двойной точности:
99999999999999982163600188718701095...и
10000000000000000159028911097599180...
другие уже объяснили, что есть около 2^62 двойников в диапазоне [0.0, 1.0].
(Не удивительно: есть почти 2^64 различных конечных двойников; из них половина положительна и примерно половина те areно вы упоминаете генераторы случайных чисел: обратите внимание, что генератор случайных чисел генерирует числа между 0.0 и 1.0 не может В общем произведите все эти числа; как правило, он будет производить только числа формы n / 2^53 с N целым числом (см., например, документацию Java для nextDouble). Так там, как правило, только около 2^53 (+/-1, в зависимости от того, какие конечные точки включены) возможные значения
random()выход. Это означает, что большинство парный в [0.0, 1.0] никогда не будут созданы.
статьи новая математика Java, Часть 2: числа с плавающей запятой от IBM предлагает следующий фрагмент кода для решения этой проблемы (в поплавках, но я подозреваю, что он работает и для двойников):
public class FloatCounter { public static void main(String[] args) { float x = 1.0F; int numFloats = 0; while (x <= 2.0) { numFloats++; System.out.println(x); x = Math.nextUp(x); } System.out.println(numFloats); } }у них есть такой комментарий по этому поводу:
оказывается, есть ровно 8,388,609 плавает между 1,0 и 2,0 включительно; большой, но вряд ли несчетная бесконечность реальных чисел, которые существуют в этом диапазоне. Последовательные номера около 0.0000001 врозь. Это расстояние называется ULP для единицы наименьшей точности или единицы в последнем месте.
- 2^53-размер значащего / мантиссы 64-битного числа с плавающей запятой, включая скрытый бит.
- примерно да, так как sifnificand фиксирован, но показатель изменяется.
посмотреть статья в Википедии для получения дополнительной информации.
Java double - это номер IEEE 754 binary64.
Это означает, что мы должны рассмотреть:
- мантисса 52 бита
- Экспонента-это 11-битное число с смещением 1023 (т. е. с добавлением к нему 1023)
- если показатель равен всем 0, а мантисса не равна нулю, то число считается ненормализованным
Это в основном означает, что есть всего 2^62-2^52+1 возможных двойных представлений, которые в соответствии с стандарт находится между 0 и 1. Обратите внимание, что 2^52+1-это удаление случаев ненормализованных чисел.
помните, что если мантисса положительна, но экспонента отрицательна, число положительно, но меньше 1 : -)
для других чисел это немного сложнее, потому что реберные целые числа могут не представляться точно в представлении IEEE 754, и потому что есть другие биты, используемые в экспоненте, чтобы иметь возможность представлять числа, поэтому чем больше число чем ниже различные значения.
Comments