pete said:
Thank you. I have more questions.
What other options are there besides positive infinity?
HUGE_VAL is required to expand into a positive double constant
expression (7.12p3). However, the C standard places no other
requirements on it, unless __STDC_IEC_559__ is #defined by the
implementation, in which case it's required to expand into an
expression with a value of positive infinity (F.9p2). As far as I can
see, if __STDC_IEC_559__ is not #defined, then it would be perfectly
legal to #define HUGE_VAL as DBL_MIN.
Could sqrt(HUGE_VAL) be undefined?
HUGE_VAL must be positive, and there's no positive number for which
sqrt() is undefined.
Is it allowed for sqrt(HUGE_VAL) to set errno to errange
if it returns HUGE_VAL?
According to 7.5p3, "The value of errno may be set to nonzero by a
library function call whether or not there is an error, provided the
use of errno is not documented in the description of the function in
this International Standard."
I could find no mention of errno in 7.12.7.5, which describes sqrt(),
so errno can be set to anything it wants. I'm not sure if that's the
intent; other parts of 7.12 describe the setting of errno in contexts
that apply to sqrt() - but that's not "in the description of the
function".
In particular, errno must be set to ERANGE if sqrt(HUGE_VAL) overflows
and math_errhandling & MATH_ERRNO is true. sqrt(HUGE_VAL) will
overflow, if and only HUGE_VAL is positive infinity.
Are any of the above 5 expressions
guaranteed to be true by the standard,
or is it merely the case that they are allowed to be true?
None of them are required by the standard unless __STDC_IEC_559__ is
#defined, in which case they are required in order to conform with IEC
559.
Suppose I want to write a 100% portable function for C89 and C99
that does exactly what log2 does. Could it be written this way?:
double l_og2(double x)
{
return log(x) / log(2);
}
The point being, Can I really on any funky values like HUGE_VAL,
which might be returned by log(x),
to not be altered by being divided by log(2)?
No.
Or would this be more portable?:
double l_og2(double x)
{
return x > 0 && DBL_MAX >= x ? log(x) / log(2) : log(x);
}
That looks good to me; but I might have missed some tricky detail.
It seems that most settings of errno to ERANGE are optional,
As, for instance, whenever 7.12p3 applies.
but for exp, it says that you do get them when the magnitude of x
is too large, not x, but the magnitude of x.
Is setting errno to ERANGE optional or mandatory for exp(-DBL_MAX)?
I think it would be a case of underflow.
On a system like mine, where HUGE_VAL is an infinity,
Is setting errno to ERANGE optional or mandatory for exp(-HUGE_VAL)?
If math_errhandling & MATH_ERRNO is true, then setting ERANGE is
mandatory for overflows and for cases where the exact value of a
function is infinite (7.12.1p4).