math.h
tags: errno.h, float.h, math.h
The math.h
header provides a large variety of mathematical functions as well
as one macro. This post will focus on just the macro while each function will
have its own dedicated post.
HUGE_VAL
The only macro in math.h
is HUGE_VAL
which is defined as "a positive
double
expression, not neceessarily representable as a float." This sounds
like a good place to use the IEEE 754 reserved value for infinity which is
described like so:
We will use the value for positive infinity so that we can represent negative
infinity by simply prepending the unary minus operator to this macro,
(-HUGE_VAL)
. A double value on x86_64 is 8 bytes in length and it will be
easiest just to represent this value with 16 hexadecimal digits:
#define HUGE_VAL (0x7FF0000000000000L)
Since a hexadecimal constant in C can't have an exponent part then we use the
L
suffix to ensure that HUGE_VAL
is interpreted as a double expression when
it is used.
Test
The test for this macro is very simple and just ensures that the file has access
to the macro through including the math.h
header:
#include <math.h>
int
math_test(void)
{
int ret = 0;
double hugeVal = 0.0;
/* Test the HUGE_VAL macro */
hugeVal = HUGE_VAL;
return ret;
}
If the test fails then a compile error will be generated:
error: ‘HUGE_VAL’ undeclared (first use in this function)
Otherwise, everything will compile and succeed.
Error Conditions
math.h
functions make use of two macros to indicate error conditions, EDOM
and ERANGE
. We already talked about these and defined them in
errno.h but we'll review them here.
A domain error occurs when an input argument is outside the domain over which
the function is defined. When this occurrs, errno
is set to EDOM
and an
implementation-defined value is returned to indicate that an error condition was
triggered.
A range errors occurs when the result of a function can't be represented as a
double
value. If the result overflows the double
type, the return value is
set to HUGE_VAL
with the same sign as the correct return value (if it was
negative then we can return (-HUGE_VAL)
) and errno
is set to ERANGE
. If
the result underflows the double
type then the return value is set to 0
. For
underflows, errno
is not required to be set to ERANGE
, but an implementation
may choose to do so. This is because the value is so small that the architecture
is not able to differentiate it from 0.
You can associate EDOM
with input errors, while ERANGE
deals with output
errors. These macros aren't used in the math.h
header itself but will be used
by most, if not all, of the functions provided by math.h
.