How to Check If C++ Compiler Uses Ieee 754 Floating Point Standard

How to check if C++ compiler uses IEEE 754 floating point standard

Actually you have an easier way to achieve this in C++. From the C++ standard 18.2.1.1 the class numeric_limits exists within std. In order to access said static member you simply do this:

std::numeric_limits<double>::is_iec559;

Or:

std::numeric_limits<float>::is_iec559;

Which should return true if IEEE 754 is in use, false otherwise.

As an alternative method, the second part of Adam's answer should do it also for C++.

How to detect non IEEE-754 float, and how to use them?

In C++, the value of std::numeric_limits<T>::is_iec559 shall be true for all floating-point types T "if, and only if, the type adheres to ISO/IEC/IEEE 60559" and ISO/IEC/IEEE 60559:2011 is the same as IEEE 754-2008, so:

#include <iostream>
#include <limits>

int main() {
std::cout << std::boolalpha << std::numeric_limits<float>::is_iec559 << '\n';
}

Note: As noted in the comments, some implementations may still report true for this constant even though their floating point types are not following the IEEE 754-2008 standard to the letter.

For example, in gcc, you can compile with the options -Ofast or -ffast-math which in turn sets a number of options which can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions.


In C99 (and later), there are conditional feature macros, __STDC_IEC_559__ and __STDC_IEC_559_COMPLEX__, that, if available in your implementation, will tell you if it's conforming to IEC 60559:1989 / IEEE 754−1985.

#include <stdio.h>
int main(void) {
#ifdef __STDC_IEC_559__
puts("true");
#endif
}

Note that if __STDC_IEC_559__ is not defined, it doesn't necessarily mean that the implementation doesn't use IEEE 754 floats. It could just mean that it doesn't have these conditional feature macros. One interesting note about these macros is that if you use -Ofast or -ffast-math in gcc, they will not be defined (unlike in the C++ test).

The actual revision of the IEC / IEEE standards used changed in C11 and C17/18 and in C23 (draft) there will be a number of new macros related to floating points and it (currently) refers to ISO/IEC 60559:2020 and IEEE 754-2019 which contains minor upgrades to IEC 60559:2011 / IEEE 754-2008.

How to check that IEEE 754 single-precision (32-bit) floating-point representation is used?

No simple test exists.

The overwhelming majority of systems today use IEEE-754 formats for floating-point. However, most C implementations do not fully conform to IEEE 754 (which is identical to IEC 60559) and do not set the preprocessor identifier __STDC_IEC_559__. In the absence of this identifier, the only way to determine whether a C implementation conforms to IEEE 754 is one or a combination of:

  • Read its documentation.
  • Examine its source code.
  • Test it (which is, of course, difficult when only exhaustive testing can be conclusive).

In many C implementations and software applications, the deviations from IEEE 754 can be ignored or worked around: You may write code as if IEEE 754 were in use, and much code will largely work. However, there are a variety of things that can trip up an unsuspecting programmer; writing completely correct floating-point code is difficult even when the full specification is obeyed.

Common deviations include:

  • Intermediate arithmetic is performed with more precision than the nominal type. E.g., expressions that use double values may be calculated with long double precision.
  • sqrt does not return a correctly rounded value in every case.
  • Other math library routines return values that may be slightly off (a few ULP) from the correctly rounded results. (In fact, nobody has implemented all the math routines recommended in IEEE 754-2008 with both guaranteed correct rounding and guaranteed bound run time.)
  • Subnormal numbers (tiny numbers near the edge of the floating-point format) may be converted to zero instead of handled as specified by IEEE 754.
  • Conversions between decimal numerals (e.g., 3.1415926535897932384626433 in the source code) and binary floating-point formats (e.g., the common double format, IEEE-754 64-bit binary) do not always round correctly, in either conversion direction.
  • Only round-to-nearest mode is supported; the other rounding modes specified in IEEE 754 are not supported. Or they may be available for simple arithmetic but require using machine-specific assembly language to access. Standard math libraries (cos, log, et cetera) rarely support other rounding modes.

If __STDC_IEC_559__ is not defined, then how to determine that FP (at least partially) conforms to IEEE 754?

There is no other relevant standard. Either the implementation mostly conforms/attempts to conform to Annex F (thus IEEE 754) or it's sufficiently broken that you can't use it for floating point. So for practical purposes, if you want to do floating point, you just document a dependence on having working floating point to the extent you need, and treat compilers that don't provide that as unsupported. There's no alternative you need to detect and also support.

C/C++: Are IEEE 754 float addition/multiplication/... and int-to-float conversion standardized?

No, unless the macro __STD_IEC_559__ is defined.

Basically the standard does not require IEEE 754 compatible floating point, so most compilers will use whatever floating point support the hardware provides. If the hardware provides IEEE compatible floating point, most compilers for that target will use it and predefine the __STD_IEC_559__ macro.

If the macro is defined, then IEEE 754 guarantees the bit representation (but not the byte order) of float and double as 32-bit and 64-bit IEEE 754. This in turn guarantees bit-exact representation of double arithmetic (but note that the C standard allows float arithmetic to happen at either 32 bit or 64 bit precision).

The C standard requires that float to int conversion be the same as the trunc function if the result is in range for the resulting type, but unfortunately IEEE doesn't actually define the behavior of functions, just of basic arithmetic. The C spec also allows the compiler reorder operations in violation of IEEE754 (which might affect precision), but most that support IEEE754 will not do that wihout a command line option.

Anecdotal evidence also suggest that some compilers do not define the macro even though they should while other compilers define it when they should not (do not follow all the requirements of IEEE 754 strictly). These cases should probably be considered compiler bugs.

How do I know what standard formats the compiler supports?

You don't, numeric_limits is clearly designed with IEEE 754 in mind. You only get to know if the implementation is IEEE 754 compliant, or not.

But keep in mind that you should use has_infinity, has_quiet_NaN etc. to check for individual features - basically, you check for certain features, not for specific floating point formats.



Related Topics



Leave a reply



Submit