I l @ ve RuBoard |
The math library contains many useful mathematical functions. The math.h header file provides the function declarations or prototypes for these functions. Table 16.1 lists several functions declared in math.h . Note that all angles are measured in radians. (One radian = 180/p = 57.296 degrees.) (Appendix F, "The Standard ANSI C Library," supplies a complete list of the functions specified by the C90 standard.)
Prototype | Description |
---|---|
double acos(double x) | Returns the angle (0 to p radians) whose cosine is x |
double asin(double x) | Returns the angle (-p/2 to p/2 radians) whose sine is x |
double atan(double x) | Returns the angle (-p/2 to p/2 radians) whose tangent is x |
double atan2(double y, double x) | Returns the angle (-p to p radians) whose tangent is y / x |
double cos(double x) | Returns the cosine of x ( x in radians) |
double sin(double x) | Returns the sine of x ( x in radians) |
double tan(double x) | Returns the tangent of x ( x in radians) |
double exp(double x) | Returns the exponential function of x (e x ) |
double log(double x) | Returns the natural logarithm of x |
double log10(double x) | Returns the base 10 logarithm of x |
double pow(double x, double y) | Returns the x to the y power |
double sqrt(double x) | Returns the square root of x |
double ceil(double x) | Returns the smallest integral value not less than x |
double fabs(double x) | Returns the absolute value of x |
double floor(double x) | Returns the largest integral value not greater than x |
Let's use the math library to solve a common problem: converting from x-y coordinates to magnitudes and angles. For example, suppose you draw, on a gridwork, a line that transverses four units horizontally (the x value), and three units vertically (the y value). What is the length (magnitude) of the line and what is its direction? Trigonometry tells us the following:
magnitude = square root (x 2 + y 2 )
and
angle = arctangent (y/x)
The math library provides a square root function and a couple of arctangent functions, so you can express this solution in a C program. The square root function, called sqrt() , takes a double argument and returns the argument's square root, also as a type double value.
The atan() function takes a double argument ”the tangent ”and returns the angle having that value as its tangent. Unfortunately, the atan() function is confused by, say, a line with x and y values of -5 and -5 . Because (-5)/(- 5) is 1, atan() would report 45 °, the same as it does for a line with x and y of 5 and 5 . In other words, atan() doesn't distinguish between a line of a given angle and one 180 ° in the opposite direction. (Actually, atan() reports in radians, not degrees; we'll discuss that conversion soon.)
Fortunately, the C library also provides the atan2() function. It takes two arguments: the x value and the y value. That way, it can examine the signs of x and y and figure out the correct angle. Like atan() , atan2() returns the angle in radians. To convert to degrees, multiply the resulting angle by 180 and divide by pi. Listing 16.10 illustrates these steps. It also gives you a chance to use structures and the typedef facility.
/* convert.c -- converts rectangular coordinates to polar */ #include <stdio.h> #include <math.h> #define RAD_TO_DEG (180/3.141592654) typedef struct polar_v { double magnitude; double angle; } POLAR_V; typedef struct rect_v { double x; double y; } RECT_V; POLAR_V rect_to_polar(RECT_V); int main(void) { RECT_V input; POLAR_V result; puts("Enter x,y coordinates; enter q to quit:"); while (scanf("%lf %lf", &input.x, &input.y) == 2) { result = rect_to_polar(input); printf("magnitude = %0.2f, angle = %0.2f\n", result.magnitude, result.angle); } return 0; } POLAR_V rect_to_polar(RECT_V rv) { POLAR_V pv; pv.magnitude = sqrt(rv.x * rv.x + rv.y * rv.y); if (pv.magnitude == 0) pv.angle = 0.0; else pv.angle = RAD_TO_DEG * atan2(rv.y, rv.x); return pv; }
Here's a sample run:
Enter x,y coordinates; enter q to quit: 10 10 magnitude = 14.14, angle = 45.00 -12 -5 magnitude = 13.00, angle = -157.38 q
If, when you compile, you get a message like
Undefined: _sqrt
or
'sqrt': unresolved external
or something similar, then your compiler-linker is not finding the math library. UNIX systems require that you instruct the linker to search the math library by using the -lm flag.
cc spring.c -lm
I l @ ve RuBoard |