случайный байт для int Java - PullRequest
       8

случайный байт для int Java

0 голосов
/ 09 ноября 2018
В классе Random определите метод nextByte, который возвращает значение байта примитивного типа.Значения, возвращаемые в последовательности вызовов, должны быть равномерно распределены по всем возможным значениям в типе. В классе Random определите метод nextInt, который возвращает значение примитивного типа int.Значения, возвращаемые в последовательности вызовов, должны быть равномерно распределены по всем возможным значениям в типе.(Подсказка: Java требует, чтобы реализации использовали представление с двойным дополнением для целых чисел. Узнайте, как вычислить случайное представление с двойным дополнением из четырех случайных байтовых значений, используя операторы сдвига Java.)

Привет, я былв состоянии выполнить часть 3, и теперь мне нужно использовать 3. для решения 4. но я не знаю, что делать.Я думал об использовании nextByte для создания массива из 4 байтов, тогда я бы взял по два дополнения каждого, чтобы у меня не было отрицательных чисел, а затем я бы собрал их в одно целое число.byte [] bytes = {42, -15, -7, 8} Предположим, что nextByte возвращает эти байты.Тогда я бы взял два дополнения каждого, которое, я думаю, было бы {42, 241, 249, 8}.Вот как это будет выглядеть и почему этот код не работает:

public static int twosComplement(int input_value, int num_bits){
    int mask = (int) Math.pow(2, (num_bits - 1));
    return -(input_value & mask) + (input_value & ~mask);
  }

Тогда я бы использовал следующее, чтобы поместить все четыре байта в int, будет ли это работать:

int i= (bytes[0]<<24)&0xff000000|
       (bytes[1]<<16)&0x00ff0000|
       (bytes[2]<< 8)&0x0000ff00|
       (bytes[3]<< 0)&0x000000ff;

Пожалуйста, будьте как можно точнее.

1 Ответ

0 голосов
/ 09 ноября 2018

Присвоение говорит, что Java уже использует два целых числа дополнения. Это полезное свойство, которое упрощает остальную часть кода: оно гарантирует, что, если вы сгруппируете 32 случайных бита (или, как правило, сколько угодно битов, которые имеет желаемый тип вывода), то это охватывает все возможные значения ровно один раз, и недопустимые значения отсутствуют. узоры.

Это может не относиться к некоторым другим целочисленным представлениям, которые могут иметь только 2³²-1 разных значений (оставляя недопустимый шаблон, который вам следует избегать) или иметь 2³² допустимых шаблонов, но одновременно с «положительным» и «отрицательным» «ноль, что приведет к тому, что случайная битовая комбинация будет иметь смещенное« интерпретированное значение »(при этом ноль встречается в два раза чаще, чем следует).

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

int i= (bytes[0]<<24)&0xff000000|
       (bytes[1]<<16)&0x00ff0000|
       (bytes[2]<< 8)&0x0000ff00|
       (bytes[3]<< 0)&0x000000ff;

Работает правильно благодаря этим свойствам. Кстати, это можно немного упростить: после сдвига влево на 24 больше не возникает проблем с расширением знака, все расширенные биты удалены. И сдвиг влево на 0, очевидно, не является операцией Так что (bytes[0]<<24)&0xff000000 можно записать как (bytes[0]<<24), а (bytes[3]<< 0)&0x000000ff как bytes[3]&0xff. Но вы можете оставить все как есть, с хорошей регулярной структурой. Функция twosComplement не требуется.

...