Сколько двузначных чисел между 0.0 и 1.0?



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



много (псевдо) генераторы случайных чисел, генерируют случайное число между 0.0 и 1.0. Математически есть бесконечные числа в этом диапазоне, но double является числом с плавающей запятой, и поэтому имеет конечную точность.



поэтому вопросы:




  1. сколько double число между 0.0 и 1.0?

  2. там так же много чисел между 1 и 2? Между 100 и 101? Между 10^100 и 10^100+1?


Примечание: если это имеет значение, я заинтересован в определении Java double в частности.

673   6  

6 ответов:

Java double s находятся в 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**52

distinct 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 для единицы наименьшей точности или единицы в последнем месте.

  1. 2^53-размер значащего / мантиссы 64-битного числа с плавающей запятой, включая скрытый бит.
  2. примерно да, так как sifnificand фиксирован, но показатель изменяется.

посмотреть статья в Википедии для получения дополнительной информации.

Java double - это номер IEEE 754 binary64.

Это означает, что мы должны рассмотреть:

  1. мантисса 52 бита
  2. Экспонента-это 11-битное число с смещением 1023 (т. е. с добавлением к нему 1023)
  3. если показатель равен всем 0, а мантисса не равна нулю, то число считается ненормализованным

Это в основном означает, что есть всего 2^62-2^52+1 возможных двойных представлений, которые в соответствии с стандарт находится между 0 и 1. Обратите внимание, что 2^52+1-это удаление случаев ненормализованных чисел.

помните, что если мантисса положительна, но экспонента отрицательна, число положительно, но меньше 1 : -)

для других чисел это немного сложнее, потому что реберные целые числа могут не представляться точно в представлении IEEE 754, и потому что есть другие биты, используемые в экспоненте, чтобы иметь возможность представлять числа, поэтому чем больше число чем ниже различные значения.

Comments

    Ничего не найдено.