В версии С99 математическая библиотека была значительно пополнена; при этом число ее функций увеличилось более чем в три раза (стандарт С89 определял всего лишь 22 математические функции). Одной из основных целей комитета по версии С99 было повышение применимости языка С для численных расчетов. Теперь с уверенностью можно сказать, что эта цель достигнута!
Для использования математических функций в программу необходимо включить заголовок <math.h>. Помимо объявления математических функций, этот заголовок определяет один или несколько макросов. В версии С89 заголовком <math.h> определяется только макрос HUGE_VAL, который представляет собой значение типа double, сигнализирующее о возникшем переполнении. В версии С99 кроме него определены следующие макросы.
HUGE_VALF | версия макроса HUGE_VAL с типом float | ||||||||||
HUGE_VALL | версия макроса HUGE_VAL с типом long doubleINFINITY | Значение, представляющее бесконечность | math_errhandling | Содержит макросы MATH_ERRNO и/или MATH_ERREXCEPT | MATHERRNO | Встроенная глобальная переменная errno, используемая для вывода сообщений об ошибках | MATH_ERREXCEPT | Исключение, возбуждаемое при выполнении операций над вещественными числами, с целью вывода сообщения об ошибках | NAN | He число | |
В версии С99 определены следующие макросы (подобные функциям), классифицирующие значение.
int fpclassify(fpval) | В зависимости от значения аргумента fpval возвращает FP_INFINITY, FP_NAN, FP_NORMAL, FP_SOBNORMAL или FP_ZERO. Эти макросы определяются заголовком <math.h> |
int isfinite(fpval) | Возвращает ненулевое значение, если fpval конечное |
int isinf(fpval) | Возвращает ненулевое значение, если fpval представляет бесконечность |
int isnan(fpval) | Возвращает ненулевое значение, если fpval — не является числом |
int isnormal(fpval) | Возвращает ненулевое значение, если fpval представляет собой нормализованное число |
int signbit(fpval) | Возвращает ненулевое значение, если fpval отрицательно (т.е. установлен его знаковый разряд) |
В версии С99 определены следующие макросы сравнения, аргументы которых (а и b) должны иметь числовые значения в формате с плавающей точкой.
int isgreater(a, b) | Возвращает ненулевое значение, если a больше b |
int isgreaterequal(a, b) | Возвращает ненулевое значение, если a больше или равно b |
int isless(a, b) | Возвращает ненулевое значение, если a меньше b |
int islessequal(a, b) | Возвращает ненулевое значение, если a меньше или равно b |
int islessgreater(a, b) | Возвращает ненулевое значение, если a больше или меньше b |
int isunordered(a, b) | Возвращает 1, если a и b не упорядочены одно по отношению к другому. Возвращает 0, если a и b упорядочены |
Эти макросы введены, так как они прекрасно обрабатывают значения, которые не являются числами, не вызывая при этом исключений вещественного типа.
Макросы EDOM и ERANGE также используются математическими функциями. Эти макросы определены в заголовке <errno.h>.
Ошибки в версиях С89 и С99 обрабатываются по-разному. Так, в версии С89, если аргумент математической функции не попадает в область определения, возвращается некоторое значение, зависящее от конкретной реализации, а встроенная глобальная целая переменная errno устанавливается равной значению EDOM. В версии С99 нарушение области определения также приводит к возврату значения, зависящего от конкретной реализации. Однако по значению math_errhandling можно судить о выполнении других действий. Если math_errhandling содержит значение MATH_ERRNO, то встроенная глобальная целая переменная errno устанавливается равной значению EDOM. Если же math_errhandling содержит значение MATH_ERREXCEPT, возбуждается исключение вещественного типа.
В версии С89, если функция генерирует результат, который слишком велик и потому не может быть представлен в машинном формате, то происходит переполнение. В этом случае функция возвращает значение HUGE_VAL, а переменная errno устанавливается равной значению ERANGE, сигнализирующему о выходе за пределы диапазона. При потере значимости функция возвращает нуль и устанавливает переменную errno равной значению ERANGE. В версии С99 ошибка переполнения также приводит к тому, что функция возвращает значение HUGE_VAL, а при потере значимости — нуль. Если math_errhandling содержит значение MATH_ERRNO, глобальная переменная errno устанавливается равной значению ERANGE, свидетельствующему об ошибке диапазона. Если же math_errhandling содержит значение MATH_ERREXCEPT, возбуждается исключение вещественного типа.
В версии С89 аргументами математических функций должны быть значения типа double, причем значения, возвращаемые функциями, тоже имеют тип double. В версии С99 добавлены варианты этих функций, работающие с типами float и long double. В этих функциях используются суффиксы f и l соответственно. Например, в версии С89 функция sin() определена следующим образом.
double sin(double arg);
Версия С99 поддерживает приведенное выше определение функции sin(), но в ней добавлены еще две ее модификации — sinf() и sinl().
float sinf (float arg);
long double sinl(long double arg);
Операции, выполняемые всеми тремя функциями, одинаковы; различаются лишь типы данных, над которыми выполняются эти операции. Добавление модификаций f и l математических функций позволяет использовать версию, которая наиболее точно соответствует данным, с которыми работают функции.
Поскольку в версии С99 добавлено так много новых функций, стоит отдельно перечислить те из них, которые поддерживаются версией С89. Это следующие функции.
acos | cos | fmod | modf | tan |
asin | cosh | frexp | pow | tanh |
atan | exp | ldexp | sin | |
atan2 | fabs | log | sinh | |
ceil | floor | log10 | sqrt |
И последнее замечание: все углы задаются в радианах.
acos
acosh
asin
asinh
atan
atan2
atanh
cbrt
ceil
copysign
cos
cosh
erf
erfc
exp
exp2
expm1
fabs
fdim
floor
fma
fmax
fmin
fmod
frexp
hypot
ilogb
ldexp
lgamma
llrint
llround
log
log10
log1p
log2
logb
lrint
lround
modf
nan
nearbyint
nextafter
nexttoward
pow
remainder
remquo
rint
round
scalbln
scalbn
sin
sinh
sqrt
tan
tanh
tgamma
trunc