Berkeley SoftFloat: Frequently Asked Questions

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 for C. No commitment is made that the source code will satisfy any other coding standards.

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 #ifdefs 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 b = 2 for binary floating-point. Note the words “computed as though the exponent range were unbounded”. To determine tininess, the floating-point implementation must act as though it temporarily rounds the result to the destination precision without regard for the exponent range. If this temporary rounded result is not in the normal exponent range for the destination format, then the tininess condition occurs.

Consider the case of converting the 64-bit double-precision value with hexadecimal pattern

to 32-bit single-precision, rounding to nearest/even. Deconstructed, the double-precision input has the value
2−127 × 1.1111111111111111111111100001000000000000000000000000
with 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.11111111111111111111111
Now, 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.00000000000000000000000
This 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.