Как реализовать drand48 и srand48 в C на Java? - PullRequest
1 голос
/ 08 июля 2019

Мне нужно реализовать генератор случайных чисел C drand48() и srand48() и инициализатор для проекта программирования, написанного на Java. Программа должна имитировать генерацию псевдослучайного числа из этих функций в C с учетом конкретного начального числа.

По справочным страницам:

Все функции работают путем генерации последовательности из 48-битных целых чисел, Xi, по линейной конгруэнтной формуле:

Xn+1 = (aXn + c) mod m, where n >= 0

Параметр m = 2 ^ 48, поэтому выполняется 48-разрядная целочисленная арифметика. Если не вызывается lcong48 (), a и c задаются как:

a = 0x5DEECE66D
c = 0xB

В этой реализации srand48(), приведенной ниже, я установил старшие 32-битные значения Xi в аргумент seedval. 16 битов младшего разряда установлены в произвольное значение 0x330E, согласно страницам руководства. Я не понимаю, как применить конгруэнтную формулу для извлечения случайного числа. Любая помощь будет принята с благодарностью, спасибо!

public void srand48(long seedval) {
  this.seed = seedval & 0xFFFFFFFF;
  this.seed = (this.seed << 16) | 0x330E;
}

public double drand48() {
  this.seed = (0x5DEECE66DL * this.seed + 0xBL) & ((1L << 48) - 1);
  return this.seed;
}

Числа, которые появляются при вызове drand48(), выходят за пределы диапазона [0.0, 1.0). Может ли кто-нибудь также объяснить, почему 48 бит так важны для генерации этого псевдослучайного числа?

1 Ответ

2 голосов
/ 08 июля 2019

Ваша реализация выглядит нормально.Полученные значения выходят за пределы диапазона, потому что вы возвращаете this.seed напрямую.Сначала вы должны нормализовать результат между 0,0 и 1,0, а затем вернуть его.Также убедитесь, что this.seed является long.

. Правильный код:

public double drand48() {
    this.seed = (0x5DEECE66DL * this.seed + 0xBL) & ((1L << 48) - 1);
    return (double)this.seed / (1L << 48);
}
...