Next Previous Contents

14. Арифметические функции низкого уровня

Эта глава содержит информацию относительно функций предназначенных для выполнения базисных арифметических операций, типа разбивания float на целую и дробную части. Эти функции объявлены в заголовочном файле "math.h ".

14.1 "Не Числовые" Значения

Формат ИИЭР с плавающей запятой используемый наиболее современными компьютерами, поддерживает значения, которые являются "не числами". Эти значения называются NaN. Эти значения следуют из некоторых операций, которые не имеют никакого значимого числового результата, типа нуля, деленого на нуль или бесконечности, деления на бесконечность.

Одна примечательная особенность NaN'ов заключается в том, что они не равны себе. Таким образом, x == x может быть 0, если значение x - NaN. Вы можете использовать это, чтобы проверить является ли значение NaN или нет: если оно не равно себе, то это - NaN. Но рекомендуемый способ проверять NaN - isnan функцией (см. Раздел 14.2 [Предикаты на Значениях с Плаваюшей точкой]).

Почти любая арифметическая операция, в которой аргумент является NaN, возвращает NaN.

    double NAN  (макрос)
Выражение, представляющее значение, которое является "не числом". Эта макрокоманда является расширением GNU, доступное только на машинах, которые поддерживают значения "not a number" то есть на всех машинах поддерживающих формат с плавающей запятой.

Вы можете использовать " #ifdef NAN " чтобы проверить, поддерживает ли машина NaN. (Конечно, Вы должны принять меры, чтобы расширения GNU были видимыми, определяя _GNU_SOURCE, и Вы должны включить " math.h ".)

14.2 Предикаты на Float

Этот раздел описывает некоторые разнообразные функции-тесты double значений. Прототипы для этих функций появляются в "math.h". Это функции BSD, и таким образом доступны, если Вы определяете _BSD_SOURCE или _GNU_SOURCE.

   int isinf (double x)  (функция)
Эта функция возвращает -1, если x представляет отрицательную бесконечность, 1, если x представляет положительную бесконечность, и 0 иначе.

    int isnan (double x)  (функция)
Эта функция возвращает значение отличное от нуля, если x - значение " not a number ", и нуль иначе. (Вы можете точно также использовать x!= x, чтобы получить тот же самый результат).

    int finite (double x)  (функция)
Эта функция возвращает значение отличное от нуля, если x конечен или значение " not a number ", и нуль иначе.

    double infnan (int error)  (функция)
Эта функция предусмотрена для совместимости с BSD. Другие математические функции используют infnan, чтобы решить, что возвратить в случае ошибки. Аргумент - код ошибки, EDOM или ERANGE; infnan возвращает подходящее значение, чтобы указать ошибку. ­ ERANGE также допустим как аргумент, и соответствует -HUGE_VAL как значение.

В библиотеке BSD, на некоторых машинах, infnan вызывает фатальный сигнал во всех случаях. Библиотека GNU не делает аналогично, потому что это не удовлетворяет спецификации ANSI C.

Примечание Переносимости: функции, перечисленные в этом разделе - расширения BSD.

14.3 Абсолютное значение

Эти функции предусмотрены для получения абсолютного значения (или величины) числа. Абсолютное значение вещественного числа x - x если x положителен, -x, если x отрицателен. Для комплексного числа z, чья вещественная часть является x и чья мнимая часть является y, абсолютное значение - sqrt (x * x + y * y).

Прототипы для abs и labs находятся в " stdlib.h "; fabs и cabs объявлены в " math.h ".

    int abs (int number)  (функция)
Эта функция возвращает абсолютное значение числа.

Большинство компьютеров использует двоичное дополнение представления integer, в котором абсолютное значение INT_MIN (самый маленький возможный int) не может представляться; таким образом, abs (INT_MIN) не определен.

    long int labs (long int number) (функция)
Подобна abs, за исключением того, что и аргумент и результат имеют тип long int а не int.

    double fabs (double number)  (функция)
Эта функция возвращает абсолютное значение числа с плавающей запятой.

    double cabs (struct { double real, imag; } z)  (функция)
Функция cabs возвращает абсолютное значение комплексного числа z, чья вещественная часть является z.real и чья мнимая часть является z.imag. (См. также функцию hypot в Разделе 13.4 [Экспоненты и Логарифмы].); значение:

    sqrt (z.real*z.real + z.imag*z.imag)

14.4 Функции Нормализации

Функциям, описанные в этом разделе прежде всего обеспечивают способ эффективно выполнить некоторые манипулирования низкого уровня на числах с плавающей запятой, которые представляются, внутренне используя двоичную систему счисления. Эти функции требуются, чтобы реализовать эквивалентное поведение, даже если представление не использует основание системы счисления 2, но конечно они, вряд ли, будут особенно эффективны в тех случаях.

Все эти функции объявлены в " math.h ".

    double frexp (double value, int *exponent)  (функция)
Frexp функция используется, чтобы разбивать значение числа на нормализованную дробь и экспоненту.

Если значение аргумента value - не нуль, возвращаемое значение value - число степеней двойки, и всегда в диапазоне от 1/2 (включ.) до 1 (исключ.). Соответствующая экспонента сохранена в *exponent; возвращаемое значение, умноженное на 2 возведенное в эту экспоненту, равняется первоначальному значению числа.

Например, frexp (12.8, &exponent) возвращает 0.8 и сохраняет 4 в exponent.

    double ldexp (double value, int exponent)  (функция)
Эта функция возвращает результат умножения значения числа с плавающей запятой на 2 в степени exponent. (Это может использоваться, чтобы повторно транслировать числа с плавающей запятой, которые были демонтированы frexp.)

Например, ldexp (0.8, 4) Возвращает 12.8.

Следующие функции, которые исходят ИЗ BSD, обеспечивают эквиваленты средств ldexp и frexp:

    double scalb (double value, int exponent)
Scalb функция - BSD имя для ldexp.

    double logb (double x)
Эта BSD функция возвращает целочисленную часть логарифма x по осн. 2, целочисленное значение представляется в double. Знак x игнорируется. Например, logb (3.5) = 1.0 и logb (4.0) = 2.0.

Когда 2 в этой степени разделена на x, это дает частное между 1 (включ.) и 2 (исключ.).

Если x - нуль, значение - минус бесконечность (если машина поддерживает такое значение), или очень малое число. Если x - бесконечность, значение - бесконечность.

Значение, возвращенное logb на один меньше чем то что frexp сохранил бы в *exponent.

    double copysign (double value, double sign) Function
Copysign функция возвращает значение, чье абсолютное значение равно указанному значению, и чей знака противоположен исходному. Это - функция BSD.

14.5 Функции Округления и Остаточного члена

Функции, перечисленные здесь выполняют операции типа округления, усечения, и взятия остаточного члена от деления чисел с плавающей запятой. Некоторые из этих функций преобразовывают числа с плавающей запятой в целочисленные значения. Они все объявлены в " math.h ".

Вы можете также преобразовывать числа с плавающей запятой в integer просто, приводя их к int. Это отбрасывает дробную часть, действительно округляя к нулю. Однако, это работает только, если результат может фактически представляться как int и для очень больших чисел, это невозможно. Функции, перечисленные здесь возвращают результат как double, чтобы обойти эту проблему.

    double ceil (double x)
Ceil функция округляет x вверх к самому близкому целому числу, возвращая это значение как double. Таким образом, ceil (1.5) = 2.0.

    double floor (double x)
floor функция округляет x вниз к самому близкому целому числу, возвращая это значение как double. Таким образом, floor (1.5) = 1.0, а floor (-1.5) = -2.0.

    double rint (double x)
Эта функция округляет x к целочисленному значению согласно текущему режиму округления.

Режим округления значения по умолчанию к самому близкому целому числу; некоторые машины поддерживают другие режимы, но этот не всегда используется если Вы явно выбираете другой.

    double modf (double value, double *integer_part)
Эта функция разбивает значение аргумента на целочисленную часть и дробную часть (между -1 и 1, не включ.). Их сумма равняется значению. Каждая из частей имеет тот же самый знак как значение, так что округление целочисленной части - к нулю.

Modf сохраняет целочисленную часть в *integer_part, и возвращает дробную часть. Например, modf (2.5, &intpart) возвращает 0.5 и сохраняет 2.0 в integer_part.

    double fmod (double numerator, double denominator)
Эта функция вычисляет остаточный член от деления numerator yf denominator. Специально, возвращаемое значение - numerator - n * denominator, где n - частное numerator/denominator, округленное к целому числу. Таким образом, fmod (6.5, 2.3) возвращает 1.9, который является 6.5-4.6.

Результат имеет тот же самый знак как numerator и имеет величину меньше чем величина denominator.

Если denominator - нуль, fmod сбоит и устанавливает errno как EDOM.

    double drem (double numerator, double denominator)  (функция)
Функция drem - подобна fmod за исключением того, что она округляет внутреннее частное n к самому близкому целому числу а не к целому числу в сторону нуля. Например, drem (6.5, 2.3) возвращает -0.4, который является 6.5-6.9.

Абсолютное значение результата - меньше или равно половине абсолютного значения denominator. Различие между fmod (numerator, denominator) и drem (numerator, denominator) - всегда либо denominator, либо -denominator, либо нуль.

Если denominator - нуль, drem сбоит и устанавливает errno как EDOM.

14.6 Целочисленное деление

Этот раздел описывает функции для выполнения деления целых чисул. Эти функции избыточны в библиотеке GNU C, с тех пор в GNU C, оператор ` / ' всегда округляется к нулю. Но в других реализациях C, " / " может поступать по-другому с отрицательными аргументами. div и ldiv полезны, потому что они определяют как округляется частное: к нулю. Остаточный член имеет тот же самый знак как числитель.

Эти функции определены, чтобы возвратить результат r такой, что значение r.quot*denominator+r.rem равняется numerator.

Чтобы использовать эти средства, Вы должны включить заглавный файл " stdlib.h " в вашей программе.

    div_t                 (тип данных)
Это - структура, используемая, чтобы содержать результат, возвращенный функцией div. Она имеет следующие элементы:
    div_t div (int numerator, int denominator)  (функция)
Эта функция вычисляет частное и остаточный член от деления numerator на denominator, возвращая результат в структуре типа div_t.

Если результат не может представляться (напр. деление на нуль), поведение не определено.

Вот пример, хотя и не очень полезный.

                        div_t result;
                        result = div (20, -6);
Теперь result.quot = -3, а result.rem = 2.

       ldiv_t             (тип данных)
Это - структура, используемая, чтобы содержать результат, возвращенный функцией ldiv. Она имеет следующие элементы:

    long int quot
Частное от деления.

    long int rem
Остаточный член от деления. (идентично div _t за исключением того, что компоненты имеют тип long int а не int.)

    ldiv_t ldiv (long int numerator, long int denominator)   (функция)
Функция ldiv подобна div, за исключением того, что аргументы имеют тип long int, и результат возвращается как структура ldiv типа.

14.7 Синтаксический анализ Чисел

Этот раздел описывает функции для "чтения" целого числа и чисел с плавающей запятой из строки. Может быть более удобно в некоторых случаях использовать sscanf или одну из подобных функций; см. раздел 7.11 [Форматируемый Ввод]. Но часто Вы можете делать программу более надежной, находя лексемы в строке вручную, и преобразуя их в числа один за другим.

Последовательный Синтаксический анализ

Эти функции объявлены в " stdlib.h ".

    long int strtol (const char *string, char **tailptr, int base)   (функция)
Strtol ("string-to-long") функция преобразовывает начальную часть строки в целое число со знаком, которое возвращено как значение long int.

Если строка является пустой, содержит только пропуск(и), или не содержит начальную подстроку, которая имеет ожидаемый синтаксис для целого числа с заданным base, никакое преобразование не выполняется. В этом случае, strtol возвращает нулевое значение, а значение, сохраненное в *tailptr - значение строки.

Если строка имеет допустимый синтаксис для целого числа, но значения не представимы из-за переполнения, strtol возвращает или LONG_MAX или LONG_MIN (см. Раздел A. 5.2 [Диапазон Типа]), соответствующее знаку значения. Она также устанавливает errno как ERANGE, чтобы указать, что имелось переполнение.

См. пример в конце этого раздела.

    unsigned long int strtoul (const char *string, char **tailptr, int base)
Strtoul ("string-to-unsigned-long") функция - подобна strtol за исключением того, что она возвращает значение с типа long unsigned int. Значение, возвращенное в случае переполнения - ULONG_MAX (см. Раздел A. 5.2 [Диапазон Типа]).

    long int atol (const char *string)  (функция)
Эта функция подобна strtol функции с аргументом base 10, за исключением того, что ей не требуется обнаруживать ошибки переполнения. Atol функция обеспечивается обычно для совместимости с существующим кодом; использование strtol более надежно.

    int atoi (const char *string)  (функция)
Эта функция - подобна atol, за исключением того, что она возвращает значение int а не long int. Atoi функция также рассматривается устаревшей; используйте strtol.

Вот функция, которая анализирует строку как последовательность целых и возвращает их сумму:

                int
                sum_ints_from_string (char *string)
                {
                        int sum = 0;
                        while (1) {
                                char *tail;
                                int next;
                                while (isspace (*string)) string++;
                                if (*string == 0)
                                        break;
                                errno = 0;
                                next = strtol (string, &tail, 0);
                                if (errno)
                                        printf ("Overflow\n");
                                else
                                        sum += next;
                                string = tail;
                        }
                        return sum;
                }

Синтаксический анализ Float

Эти функции объявлены в " stdlib.h ".

    double strtod (const char *string, char **tailptr)  (функция)
Strtod ("string-to-double") функция преобразовывает начальную часть строки в число с плавающей запятой, которое возвращается как значение double.

Эта функция пытается разлагать строку следующим образом:

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

В этом случае, strtod возвращает нуль, а значение, возвращенное в *tailptr - значение строки.

В стандарте отличном от стандарта "C", эта функция может распознавать дополнительный синтаксис.

Если строка имеет допустимый синтаксис для числа с плавающей запятой, но значения, не представимы из-за переполнения, strtod возвращает или положительный или отрицательный HUGE_VAL (см. Главу 13 [Математика]), в зависимости от знака значения. Аналогично, если значение не представимо из-за близости к нулю, strtod возвращает нуль. Она также устанавливает errno как ERANGE, если имелось переполнение или обнуление.

    double atof (const char *string)  (функция)
Эта функция подобна функции strtod, за исключением того, что ей не требуется обнаруживать ошибки переполнения. Atof обеспечивают обычно для совместимости с существующим кодом; использование strtod более надежно.


Next Previous Contents