John R. Hauser
2018 June 2
Q:
When I compile SoftFloat with my favorite C compiler, it reports a small (or
large) number of warnings about the code.
Can’t SoftFloat’s code be fixed to eliminate those warning
messages?
A:
SoftFloat is written to be valid only according to the ISO Standard
While compiler warning messages can be helpful for finding bugs, not every
warning indicates a bug, nor are there any limits on what compilers may warn
about.
A simple increment of a variable, ++n
, for instance, can
legitimately elicit a warning that the increment might overflow.
It has even been observed that, where one compiler required adding an explicit
type cast to suppress a warning, another compiler warned that the added cast
was superfluous!
In such a case, a single source file could not make both compilers happy, short
of using #ifdef
s to specialize the code for each compiler.
Furthermore, systemized attempts to suppress compiler warnings (by regularly
inserting extra type casts, for example) can sometimes have the undesirable
effect of also suppressing useful error messages.
When a project constrains itself to using just one C compiler, or a limited
number of known compilers, with a specific set of compiler options (such as
-Wall
or -Wextra
), then the set of possible warnings
is bounded by the chosen compilers and options, and it may be feasible to
demand that source code be written to sidestep all compiler warnings.
Even then, to satisfy this requirement, programmers have been known to fall
back on an occasional #pragma
or other compiler-specific directive
to quiet spurious warnings in certain circumstances.
SoftFloat is not written for any particular C compiler, and warning messages are outside the scope of the standard to which SoftFloat strives to conform. This stance could be reconsidered if and when there is a widely adopted standard for C compiler warnings, including a standard way for C code to suppress specific warning messages when they are known to be spurious.
Q:
I discovered a case where, even though tininess is set to be detected after
rounding, SoftFloat raises the underflow flag for a result that is not a
subnormal or zero but is instead in the normal range.
Isn’t this a bug in SoftFloat?
A: Probably not. There are certain cases right at the underflow threshold for which the IEEE Floating-Point Standard requires this very behavior.
The standard mandates that the underflow flag is raised when the result of an operation is inexact and tininess is detected. The inexact condition is easy enough to understand, so that leaves tininess. The standard says that, when tininess is detected after rounding, tininess occurs
when a non-zero result computed as though the exponent range were unbounded would lie strictly between ±bemin,where
Consider the case of converting the
380FFFFFE1000000
to 2−127 × 1.1111111111111111111111100001000000000000000000000000with the significand bits written in binary. The conversion function only needs to round this value to the single-precision format. If we ignore exponent range and round the significand to the same precision as the single-precision format, we get this value:
2−127 × 1.11111111111111111111111Now, if the exponent here were in range for the single-precision format, this is the value that would be returned as the result of the conversion. However, the exponent is not in range (emin for single-precision is −126), and, furthermore, this value is not representable in the single-precision format even as a subnormal number. Hence, rounding the original double-precision value to the nearest representable single-precision number gives a slightly different answer:
2−126 × 1.00000000000000000000000This happens to be a normal number for single-precision. Nevertheless, following the IEEE Standard’s rules, we can see both that the tininess condition is true (from our first attempt at rounding above) and that the result is inexact, so the underflow flag must be raised.