Я пишу приложение в среде с функциями
- 36 бит целых чисел.
- арифметика ограничена
+
,-
,*
,/
и остатком - нет операций с битами типа
AND
илиOR
. Но из-за одного дополненияXOR
эквивалентно вычитанию, аNOT
- отрицанию. - числовое переполнение является фатальным, поэтому его нельзя использовать для тихой усечения
- Да, есть условные обозначения:
IF/THEN/ELSEIF/ELSE/IF
.
В идеале мне бы хотелось получить 35 или 36 бит случайных целых чисел, но также было бы достаточно 25 бит.
Мои наивные реализации линейного конгруэнтного генератора запускаются в переполнение, если они основаны на достаточно больших числах и производят только небольшое количество бит, когда я использую меньшие числа.
Итак, я ищу либо набор чисел a, c, m, который даст максимальное количество бит в ограничениях, либо разумную адаптацию LCG для объединения двух или более чисел.
В качестве отправной точки, вот что я использую до сих пор:
*DEFINE NextRandom . min,max resultVar
* . This is a very shitty RNG. The numbers were never checked
* . for suitability for a long-period linear congruential generator.
* . But it yields numbers that look vaguely random.
*CLEAR rq
*CLEAR rr
*SET RandZ = RandZ * 169687 + 347011 . RandZ is a global var.
*DIVIDE RandZ BY 131072 GIVING rq, RandZ . Division yields a remainder
*DIVIDE RandZ BY 4 GIVING rq
*SET r0 = +[#,[#],1,1] . r0 = argument 'min'
*SET r9 = +[#,[#],1,2] . r9 = 'max'
*SET rd = r9 - r0 + 1
*DIVIDE rq BY rd GIVING rq, rr
*SET [#,[#],2,1] TO r0 + rr . return in 'resultVar'
*ENDDEFINE
В случае, если кто-то заботится, язык сценариев является SSG (Symbolic Stream Generator) в операционной системе UNISYS 2200 под управлением EXEC 8.
О критичности: приложение, в котором работает этот RNG, генерирует тестовые данные. Он не шифрует государственные секреты или коды ядерных ракет. Поэтому мы говорим о том, что "приятно иметь" и "лучше всего", а не "критически важно". Я был бы доволен улучшением, но не искал окончательного решения.