Many routines in the libm library are more highly optimized for Intel® microprocessors than for non-Intel microprocessors.
To use the Intel® Math Library, include the header file, mathimf.h, in your program. The following example programs illustrate the use of the math library on Windows* operating systems.
// real_math.c
#include <stdio.h>
#include <mathimf.h>
int main()
{
float fp32bits;
double fp64bits;
// /Qlong-double compiler option required because, without it,
// long double types are mapped to doubles.
long double fp80bits;
long double pi_by_four = 3.141592653589793238/4.0;
// pi/4 radians is about 45 degrees
fp32bits = (float) pi_by_four;
// float approximation to pi/4
fp64bits = (double) pi_by_four;
// double approximation to pi/4
fp80bits = pi_by_four;
// long double (extended) approximation to pi/4
// The sin(pi/4) is known to be 1/sqrt(2) or approximately .7071067
printf("When x = %8.8f, sinf(x) = %8.8f \n",
fp32bits, sinf(fp32bits));
printf("When x = %16.16f, sin(x) = %16.16f \n",
fp64bits, sin(fp64bits));
printf("When x = %20.20f, sinl(x) = %20.20f \n",
(double) fp80bits, (double) sinl(fp80bits));
// printf() does not support the printing of long doubles
// on Microsoft Windows*, so fp80bits is cast to double in this example.
return 0;
}
Since the real_math.c program includes the long double data type, be sure to include the /Qlong-double and /Qpc80 compiler options in the command line:
icl /Qlong-double /Qpc80 real_math.c
The output of real_math.exe looks like this:
When x = 0.78539816, sinf(x) = 0.70710678
When x = 0.7853981633974483, sin(x) = 0.7071067811865475
When x = 0.78539816339744828, sinl(x) = 0.70710678118654746
// complex_math.c
#include <stdio.h>
#include <complex.h>
int main()
{
float _Complex c32in,c32out;
double _Complex c64in,c64out;
double pi_by_four= 3.141592653589793238/4.0;
c64in = 1.0 + I* pi_by_four;
// Create the double precision complex number 1 + pi/4 I
// where I is the imaginary unit.
c32in = (float _Complex) c64in;
// Create the float complex value from the double complex value.
c64out = cexp(c64in);
c32out = cexpf(c32in);
// Call the complex exponential,
// cexp(z) = cexp(x+Iy) = e^ (x + i y) = e^x * (cos(y) + i sin(y))
printf("When z = %7.7f + %7.7f I, cexpf(z) = %7.7f + %7.7f I \n",
crealf(c32in),cimagf(c32in),crealf(c32out),cimagf(c32out));
printf("When z = %12.12f + %12.12f I, cexp(z) = %12.12f + %12.12f I \n",
creal(c64in),cimag(c64in),creal(c64out),cimagf(c64out));
return 0;
}
Since this example program includes the _Complex data type, be sure to include the /Qc99 compiler option in the command line:
icl /Qstd=c99 complex_math.c
The output of complex_math.exe looks like this:
When z = 1.0000000 + 0.7853982 I, cexpf(z) = 1.9221154 + 1.9221156 I
When z = 1.000000000000 + 0.785398163397 I, cexp(z) = 1.922115514080 + 1.922115514080 I
_Complex data types are supported in C but not in C++ programs.
Exception ConditionsIf you call a math function using argument(s) that may produce undefined results, an error number is assigned to the system variable errno. Math function errors are usually domain errors or range errors.
Domain errors result from arguments that are outside the domain of the function. For example, acos is defined only for arguments between -1 and +1 inclusive. Evaluating acos(-2) or acos(3) results in a domain error, and the return value is QNaN.
Range errors occur when a mathematically valid argument results in a function value that exceeds the range of representable values for the floating-point data type. Evaluating exp(1000) results in a range error, and the return value is INF.
When domain or range error occurs, the following values are assigned to errno:
domain error (EDOM): errno = 33
range error (ERANGE): errno = 34
The following example shows how to read the errno value for an EDOM and ERANGE error.
// errno.c
#include <errno.h>
#include <mathimf.h>
#include <stdio.h>
int main(void)
{
double neg_one=-1.0;
double zero=0.0;
// The natural log of a negative number is considered a domain error - EDOM
printf("log(%e) = %e and errno(EDOM) = %d \n",neg_one,log(neg_one),errno);
// The natural log of zero is considered a range error - ERANGE
printf("log(%e) = %e and errno(ERANGE) = %d \n",zero,log(zero),errno);
}
The output of errno.c looks like this:
log(-1.000000e+00) = nan and errno(EDOM) = 33
log(0.000000e+00) = -inf and errno(ERANGE) = 34
For the math functions in this section, a corresponding value for errno is listed when applicable.
Some math functions are inlined automatically by the compiler. The functions inlined may vary from library counterparts and may depend on the vectorization or processor-specific compilation options used. You may disable automatic inline expansion of all functions by compiling your program with the /Oi- option.
A change of the default precision control or rounding mode may affect the results returned by some of the mathematical functions.
Depending on the data types used, some important compiler options include:
/Qlong-double: Use this option when compiling programs that require support for the long double data type (80-bit floating-point). Without this option, compilation will be successful, but long double data types will be mapped to double data types. This option is valid for IA-32, Intel® 64, and IA-64 architectures running Windows* operating systems.
/Qstd=c99: Use this option when compiling programs that require support for _Complex data types. This option is valid for IA-32, Intel® 64, and IA-64 architectures running Windows* operating systems.
Copyright © 1996-2010, Intel Corporation. All rights reserved.