Thursday, June 16, 2011

Mathematical Functions

8.  <math.h>  Mathematical Functions

The header <math.h> declares mathematical functions and macros.
The macros EDOM and ERANGE (in <errno.h>) are non-zero integral constants that are used to signal domain and range errors for the functions; HUGE_VAL is a positive double value. A domain error occurs if an argument is outside the domain over which the function is defined. On a domain error, errno is set to EDOM; the return value is implementation-defined. A range error occurs if the result of the function cannot be represented as a double. If the result overflows, the function returns HUGE_VAL with the right sign, and errno is set to ERANGE. If the result underflows, the function returns zero; whether errno is set to ERANGE is implementation-defined.
In the following table, x and y are of type double, n is an int, and all functions return double. Angles for trigonometric functions are expressed in radians.

sin(x)
sin(x)
cos(x)
cos(x)
tan(x)
tan(x)
asin(x)
sin-1(x) in range [-π/2, π/2], x in [-1, 1].
acos(x)
cos-1(x) in range [0, π], x in [-1, 1].
atan(x)
tan-1(x) in range [-π/2, π/2].
atan2(y, x)
tan-1(y/x) in range [-π, π].
sinh(x)
hyperbolic sine of x
cosh(x)
hyperbolic cosine of x
tanh(x)
hyperbolic tangent of x
exp(x)
exponential function ex
log(x)
natural logarithm ln(x), x>0.
log10(x)
base 10 logarithm log10(x), x>0.
pow(x, y)
xy. A domain error occurs if x=0 and y<=0, or if x<0 and y is not an integer.
sqrt(x)
square root of x, x>=0.
fabs(x)
absolute value |x|
ceil(x)
smallest integer not less than x, as a double.
floor(x)
largest integer not greater than x, as a double.
ldexp(x, n)
x*2n
frexp(x, int *exp)
splits x into a normalized fraction in the interval [0.5, 1) that is returned, and a power of 2, which is stored in *exp. If x is zero, both parts of the result are zero.
modf(x, double *ip)
splits x into integral and fractional parts, each with the same sign as x. It stores the integral part in *ip, and returns the fractional part.
fmod(x, y)
floating-point remainder of x/y, with the same sign as x. If y is zero, the result is implementation-defined. Cf.) div, ldiv (in <stdlib.h>)

EXAMPLE CODES
1.       math.h
l math-1.c
#include <stdio.h>
#include <math.h>

#define PI 3.1415926535
#define E  2.7182818285
#define DEGREE2RADIAN(x) ((x) * PI / 180)
#define RADIAN2DEGREE(x) ((x) / PI * 180)
#define ROUND(x) floor((x) + 0.5)

void main() {
    printf("%g\n", sin(DEGREE2RADIAN(30)));        // 0.5
    printf("%g\n", cos(DEGREE2RADIAN(60)));        // 0.5
    printf("%g\n", tan(DEGREE2RADIAN(45)));        // 1
    putchar('\n'); //---------------------
    printf("%g\n", RADIAN2DEGREE(asin(0.5)));      // 30
    printf("%g\n", RADIAN2DEGREE(acos(0.5)));      // 60
    printf("%g\n", RADIAN2DEGREE(atan(1.0)));      // 45
    putchar('\n'); //---------------------
    printf("%+g\n", RADIAN2DEGREE(atan2(+1, +1))); // +45
    printf("%+g\n", RADIAN2DEGREE(atan2(-1, +1))); // -45
    printf("%+g\n", RADIAN2DEGREE(atan2(+1, -1))); // +135
    printf("%+g\n", RADIAN2DEGREE(atan2(-1, -1))); // -135
    putchar('\n'); //---------------------
    printf("%g %g\n", sinh(1), (exp(1)-exp(-1)) / 2);  // 1.1752 1.1752
    printf("%g %g\n", cosh(1), (exp(1)+exp(-1)) / 2);  // 1.54308 1.54308
    printf("%g %g\n", tanh(1), sinh(1) / cosh(1));     // 0.761594 0.761594
    putchar('\n'); //---------------------
    printf("%.11g\n", exp(1));                     // 2.7182818285
    printf("%g\n", log(E));                        // 1
    printf("%g\n", log10(100));                    // 2
    printf("%g\n", log(1024) / log(2));            // 10 -- log2(1024)
    printf("%g\n", pow(2, 10));                    // 1024
    putchar('\n'); //---------------------
    printf("%g\n", pow(10, 310));                  // 1.#INF
    printf("%g\n", HUGE_VAL);                      // 1.#INF
    perror("pow");                                 // pow: Result too large
    putchar('\n'); //---------------------
    printf("%g\n", sqrt(2.0));                     // 1.41421
    printf("%g\n", fabs(-3.4));                    // 3.4
    putchar('\n'); //---------------------
    printf("%+g %+g\n", ceil(-2.5),  ceil(+2.5));  // -2 +3
    printf("%+g %+g\n", floor(-2.5), floor(+2.5)); // -3 +2
    printf("%+d %+d\n", (int)-2.5,   (int)+2.5);   // -2 +2 -- truncate
    printf("%+g %+g\n", ROUND(2.4), ROUND(2.6));   // +2 +3
}
l math-2.c
#include <stdio.h>
#include <math.h>
void main() {
    int e;
    double m, f_part, i_part;

    printf("%g\n", ldexp(4.0, 3));     // 32 -- 4.0 * 2^3 = 32.0
    m = frexp(32.0, &e);               // -- 32.0 = 0.5 * 2^6
    printf("%g: mantissa = %g, exponent = %d\n", 32.0, m, e);
        // 32: mantissa = 0.5, exponent = 6
    putchar('\n'); //---------------------
    f_part = modf(-3.4, &i_part);      // -- -3.4 = -3 + -0.4
    printf("%g: integer = %g, fraction = %g\n", -3.4, i_part, f_part);
        // -3.4: integer = -3, fraction = -0.4
    printf("%d %g\n", (int)-3.4, -3.4 - (int)-3.4);    // -3 -0.4
    putchar('\n'); //---------------------
                   // sign of the remainder: sign of the numerator
    printf("%+g\n", fmod(+1.0, +0.3)); // +0.1 -- +1.0 = +0.3 * +3 + +0.1
    printf("%+g\n", fmod(+1.0, -0.3)); // +0.1 -- +1.0 = -0.3 * -3 + +0.1
    printf("%+g\n", fmod(-1.0, +0.3)); // -0.1 -- -1.0 = +0.3 * -3 + -0.1
    printf("%+g\n", fmod(-1.0, -0.3)); // -0.1 -- -1.0 = -0.3 * +3 + -0.1
    putchar('\n'); //---------------------
    printf("%g\n", fmod(1.0, 0.0));        // -1.#IND
    perror("fmod");                        // fmod: Domain error
}

No comments: