Страница 3 из 3
Самый быстрый генератор для 32-битового представления целых и действительных чисел В большинстве случаев, число типа unsigned long имеет 32 бита. В этом случае для генерации числа в диапазоне 0 - 232-1 достаточно простого умножения на мультипликатор и сложения с инкрементом. Деление по модулю будет произведено автоматически при переполнении. Значения мультипликатора и инкремента для этого случая получены в исследованиях Кнута и Льюиса. /* генерация целого числа от 0 до 0xFFFFFFFF. */ static unsigned long iran; ........... // целое случайное число iran=1664525L*iran+1013904223L;
Для реализации на этой основе очень быстрого генератора равномерного распределения действительных чисел от 0 до 1 важно, что числа с плавающей точкой одинарной точности (тип float) в большинстве случаев представлены также 32 битами. Кроме того, во многих случаях (включая SUN, ALPHA, Silicon Graphics и IBM PC) представление этого числа отвечает одному стандарту IEEE. Для машины VAX это не так. Грязным трюком, позволяющим избегнуть деления на действительное число, является маскировка экспоненты и дальнейшее вычитание из числа единицы. Необходимые коэффициенты в программе приведены для IEEE (по умолчанию) и для VAX. static unsigned long iran; unsigned long temp; float fran; .......... #if !defined(VAX) static unsigned long jflone=0x3f800000; static unsigned long jflmsk=0x007fffff; #else static unsigned long jflone=0x00004080; static unsigned long jflmsk=0xffff007f; #endif .......... iran=1664525L*iran+1013904223L; temp=jflone|(jflmsk&iran); // случайное число с плавающей точкой fran=(*(float *)&temp)-1.F;
С точки зрения программиста, занимающегося численными методами, а не железом, этот генератор является "особо грязным", поскольку реализация зависит от представления чисел в компьютере. Впрочем, этот генератор в подавляющем большинстве практических случаев работает верно, а главное - очень быстро. |