int val = rand()%max;
Долгое время такой код считался совершенно неудовлетворительным, поскольку он просто отбрасывает младшие разряды случайного числа, а они, как правило, не обладают свойствами, которыми должны обладать числа, генерируемые традиционными датчиками случайных чисел. Однако в настоящее время во многих операционных системах эта проблема решена достаточно успешно, но для обеспечения переносимости своих программ мы рекомендуем все же скрывать вычисления случайных чисел в функциях.
int randint(int max) { return rand()%max; }
int randint(int min, int max) { return randint(max–min)+min; }
randint()
, если окажется, что реализация функции rand()
является неудовлетворительной. В промышленных программных системах, а также в приложениях, где требуются неравномерные распределения, обычно используются качественные и широко доступные библиотеки случайных чисел, например Boost::random
. Для того чтобы получить представление о качестве вашего датчика случайных чисел, выполните упр. 10.
24.8. Стандартные математические функции
В стандартной библиотеке есть стандартные математические функции (cos
, sin
, log
и т.д.). Их объявления можно найти в заголовке
.
Стандартные математические функции могут иметь аргументы типов float
, double
, long double
и complex
(раздел 24.9). Эти функции очень полезны при вычислениях с плавающей точкой. Более подробная информация содержится в широко доступной документации, а для начала можно обратиться к документации, размещенной в веб.
errno
. Рассмотрим пример.
errno = 0;
double s2 = sqrt(–1);
if (errno) cerr << "Что-то где-то пошло не так, как надо";
if (errno == EDOM) // ошибка из-за выхода аргумента
// за пределы области определения
cerr << " фунция sqrt() для отрицательных аргументов
не определена.";
pow(very_large,2); // плохая идея
if (errno==ERANGE) // ошибка из-за выхода за пределы допустимого
// диапазона
cerr << "pow(" << very_large
<< ",2) слишком большое число для double";
Если вы выполняете серьезные математические вычисления, то всегда должны проверять значение errno
, чтобы убедиться, что после возвращения результата оно по-прежнему равно 0
. Если нет, то что-то пошло не так, как надо. Для того чтобы узнать, какие математические функции могут устанавливать флажок errno
и чему он может быть равен, обратитесь к документации.
errno
просто означает, что что-то пошло не так. Функции, не входящие в стандартную библиотеку, довольно часто также устанавливают флажок errno
при выявлении ошибок, поэтому следует точнее анализировать разные значения переменной errno
, чтобы понять, что именно случилось. В данном примере до вызова стандартной библиотечной функции переменная errno
была равна нулю, а проверка значения errno
сразу после выполнения функции может обнаружить, например, константы EDOM
и ERANGE
. Константа EDOM
означает ошибку, возникшую из-за выхода аргумента за пределы области определения функции (domain error). Константа ERANGE
означает выход за пределы допустимого диапазона значений (range error).
Обработка ошибок с помощью переменной errno
носит довольно примитивный характер. Она уходит корнями в первую версию (выпуска 1975 года) математических функций языка C.
24.9. Комплексные числа
Комплексные числа широко используются в научных и инженерных вычислениях. Мы полагаем, что раз они вам необходимы, значит, вам известны их математические свойства, поэтому просто покажем, как комплексные числа выражаются в стандартной библиотеке языка С++. Объявление комплексных чисел и связанных с ними математических функций находятся в заголовке
.
template
// комплексное число — это пара скалярных величин,
// по существу, пара координат
Scalar re, im;
public:
complex(const Scalar & r, const Scalar & i) :re(r), im(i) { }
complex(const Scalar & r) :re(r),im(Scalar ()) { }
complex() :re(Scalar ()), im(Scalar ()) { }