Почему Oracle утверждает, что java.util.Random.nextFloat () генерирует 2 ^ 24 возможностей, а не 2 ^ 23? - PullRequest
5 голосов
/ 23 сентября 2019

Согласно документации для java.util.Random , класс Java реализует nextFloat на next(24) / ((float)(1 << 24)) (т. Е. Случайное неотрицательное целое число с 24 битами, разделенными на 2 24).В документации утверждается, что все 2 24 возможных значений могут быть возвращены.Они между 0 (включительно) и 1 (исключительно).Однако я не думаю, что это правда.

Во-первых, обратите внимание, что в соответствии со стандартом IEC 559 (IEEE 754), float имеет 23 бита дроби.Но есть неявный ведущий бит (слева от двоичной точки) со значением 1, если показатель степени не хранится со всеми нулями.Таким образом, верно, что существует всего 2 24 значения типа float, которые находятся между 0 (включительно - не считая отрицательного нуля) и 1 (исключая), но ровно половина этих чиселсубнормальный (все биты в экспоненте равны 0), что делает их все менее 2 -126 .Следовательно, ни одно из этих чисел не может быть сгенерировано реализацией.Это потому, что все они строго меньше, чем 2 -24 , который используется в реализации.

Макет float можно найти в с плавающей точкой одинарной точностиформат .

Так чего же мне не хватает?

Ответы [ 2 ]

5 голосов
/ 23 сентября 2019

В интервале [+0, 1) имеется 127 • 2 23 значений, представленных в float, а не 2 24 .Существует один для каждой комбинации поля кодирования экспоненты от 0 до 126 включительно, с каждым значением 23 битов в поле значимости и кодирования.

Каждое значение в форме m • 2 −24 , с 0 ≤ m <2 <sup>24 , представимо.Наименьшее ненулевое значение в этой форме равно 2 -24 , что представлено кодом экспоненты 103 и значимым кодом 0. 0. Математическим показателем является код 103, минус смещение, 127, что равно −24, а математическое значение равно 1.

. Для любого такого m , отличного от нуля, пусть b будет номером позиции его старшего 1 бита(нумерация от 0 для младшего бита).Затем m • 2 −24 кодируется в float с кодом экспоненты b + 103 и значимым кодом m • 2 24− b -2 24 .Для m = 0 он кодируется всеми нулевыми битами.

Ни одно из чисел в этой форме не является ненормальным.

0 голосов
/ 23 сентября 2019

Каждое число типа float имеет 23 дробных бита и 8 экспоненциальных битов.Мы покажем, как использовать float для точного представления каждого числа n в форме 0.b 1 b 2 b 3 ... b 24 .Пусть i будет наименьшим числом таким, что b i не равен нулю.Если такого i не существует, то n=0, который может быть представлен в float.В противном случае n = 2 -i 2 i 0.b 1 b 2 b 3 ...б 24 .Часть 2 -i может быть четко представлена ​​8 битами показателей степени в float.Кроме того, часть 2 i 0.b 1 b 2 b 3 ... b 24 являетсявида 1.b i + 1 b i + 2 ... b 24 , который имеет не более 23 битов дроби.Следовательно, n может быть точно представлено в float.

Все, что остается, - это равномерно генерировать случайные целые числа вида b 1 b 2 b 3 ... b 24 , а затем разделите их на 2 24 , что именно то, что предлагает Oracle.

...