In C99, several features were added that addressed rounding:
the macro FLT_ROUNDS was added to <float.h>; it expands to an expression
that will indicate the current rounding mode.
"A floating expression may be contracted, that is, evaluated as though
it were a single operation, thereby omitting rounding errors implied by
the source code and the expression evaluation method.89) The FP_CONTRACT
pragma in <math.h> provides a way to disallow contracted expressions."
(6.5p8)
fegetround() gets the current rounding direction, fesetround() sets it.
The possible rounding directions are identified by macros #defined in
<fenv.h>. They are all optional: #ifndef, the corresponding rounding
direction is not supported.
Several new functions were added to <math.h> for rounding to an integer
in various ways: nearbyint(), lrint(), round().
... I don't normally use floating point calculations if I don't
I think C is a little stricter, but there is a claim that a valid
Fortran floating point system could return 42.0 (or 42.D0) for all
floating point expressions.
C is a little stricter than that: Conversions to floating point type are
required to result in the nearest higher or nearest lower representable
value (6.3.1.4, 6.3.1.5), so (double)196 is not allowed to have a value
of 42.0. Also, "For decimal floating constants, and also for hexadecimal
floating constants when FLT_RADIX is not a power of 2, the result is
either the nearest representable value, or the larger or smaller
representable value immediately adjacent to the nearest representable
value, chosen in an implementation-defined manner.
For hexadecimal floating constants when FLT_RADIX is a power of 2, the
result is correctly rounded." (6.4.4.2p3), so the floating point
expression 3.0 is not allowed to have a value of 42.0. Also, all
floating point comparison operators (<, >, <=, >=, ==, !=) are required
to return either 0 or 1, and they must return the correct value - they
are not allowed to perform fuzzy comparisons.
However, unless an implementation of C chooses to pre-#define
__STDC_IEC_559__, in all other regards C is not very strict at all: "The
accuracy of the floating-point operations (+, -, *, /) and of the
library functions in <math.h> and <complex.h> that return floating-point
results is implementation defined, as is the accuracy of the conversion
between floating-point internal representations and string
representations performed by the library functions in <stdio.h>,
<stdlib.h>, and <wchar.h>. The implementation may state that the
accuracy is unknown."
Therefore, a conforming implementation of C is allowed to evaluate the
division in DBL_MIN/DBL_MAX < DBL_MAX with such lousy accuracy that the
comparison ends up being false.
If __STDC_IEC_559__ is pre-#defined, the implementation must conform to
the requirements of Annex K, which is based upon, but not identical
with, IEC 60559 (which in turn, is essentially equivalent to IEEE 754).
In that case, the floating point accuracy requirements are quite strict
- they come pretty close to being as strict as it is practically
possible for them to be. Which is still to low a requirement for this
kind of use.