Функция C stdlib rand () в Java - PullRequest
       15

Функция C stdlib rand () в Java

1 голос
/ 09 февраля 2012

Я сгенерировал серию случайных чисел из известного начального числа в C, используя srand() и rand() из stdlib. Теперь мне нужно сгенерировать те же серии чисел, используя то же начальное число из C в Java.

Документация класса Java Random гласит, что она использует "линейную конгруэнтную формулу". Документация, которую я нашел на rand(), говорит, что в ней используется «линейный конгруэнтный» генератор, хотя я не уверен, что это для одной конкретной реализации.

Кто-нибудь знает, будут ли оба генератора генерировать одинаковые числа, если для них задано одинаковое начальное число, или для Java существует порт srand() и rand()?

Ответы [ 3 ]

6 голосов
/ 09 февраля 2012

Стандарт C не предписывает реализации srand () и rand ().Таким образом, различные среды (ОС, библиотеки C, архитектура и т. Д.), Скорее всего, будут создавать последовательности чисел, которые различаются для одного и того же начального значения.

Кроме того, класс Java реализации не связан слюбой конкретный алгоритм.Здесь снова, разные JVM могут очень хорошо производить разные последовательности для одного и того же начального значения.Кроме того, реализация, скорее всего, не будет привязана к стандартным функциям C.Это означает, что созданная Java последовательность будет отличаться от последовательности C с использованием того же начального числа.

Если вам действительно нужно сгенерировать случайную последовательность в Java, чтобы точно соответствовать последовательности стандартных функций C, лучшее, на что вы могли бы надеятьсясделать, это повторить последовательность для конкретной среды.Это потребует создания библиотеки JNI для прокси-вызовов srand () и rand () или создания какого-либо другого внешнего процесса, который выполняет вызовы и вызывается из Java.В любом случае, это большая сложность и дополнительное обслуживание программы.

Если на самом деле все, что вам нужно, это случайные последовательности, которые кажутся равномерно распределенными, независимо от точных значений, то используйте Random как есть.Этого более чем достаточно для большинства нужд ГСЧ.

1 голос
/ 09 февраля 2012

Как сказано в другом ответе, стандарт C даже не указывает, что rand() будет возвращать одну и ту же последовательность на разных платформах (библиотеках) C, и ничто в Java не гарантирует, что он соответствует любому данному C (или другой Java). ) реализация. Вы могли бы использовать JNI для вызова конкретной реализации C на этой платформе, но это гарантировало бы, что одна и та же последовательность будет создаваться, когда программы на C и Java выполняются на одной и той же платформе с использованием одной и той же библиотеки C.

Если вы хотите обеспечить одинаковую последовательность во всех ситуациях, вам необходимо реализовать один и тот же генератор случайных чисел на обоих языках. Простой пример можно найти в POSIX.1-2001, и он цитируется на многих man 3 rand страницах:

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned seed) {
    next = seed;
}

Он легко переносится на Java. Качество случайности, создаваемое этим генератором, не очень высокое, но на самом деле с rand() также не гарантировано, что оно будет лучше, поэтому вам потребуется реализовать что-то более изощренное, если требуется лучшая случайность.

0 голосов
/ 09 февраля 2012

И в C, и в Java одно и то же начальное число будет генерировать одинаковые случайные значения. Хотя базовый механизм может отличаться, это свойство поддерживается на каждом языке программирования, о котором я знаю.

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

...