Binding for IEEE-754.
DannyNiu/NJF 2026-08.
1. Overview
This document is purposed as a personal attempt at rewording parts of the IEEE-754 standard for floating point arithmetic, to make the text more concise, intuitive, and straightforward for people with appropriate background (such as programming) to understand. It's not the standard proper, nor is the author affiliated with the developing body of the standard.
The parts reworded include
- parts of chapter 2 on definitions, needed as foundation of the rewording.
- parts of chapter 4 on attributes but not on rounding,
- parts of chapter 7 on the scoping of some attributes and flags,
- chapter 8 on alternate exception handling attributes p.k.a. traps,
This document also contain commentary with personal opinion on:
- chapter 10 on evaluation of "expressions".
- chapter 11 on reproducibility.
The original 1985 edition of the standard concerned only with a model program instructions would execute in sequence, with floating point arithmetic computed by the processor, consulting modes for rounding and trap handling, and setting status flags on exceptional conditions.
Reproducibility was a major concern of the 2008 revision. The approach taken back then, was to reword the standard in terms of requirements for languages contrasting previously which was in terms of requirements for computing hardwares.
We'd like to note that, assembly languages are also languages, and we are going to take this particular fact into account for our rewording.
The 2019 revision of the standard was a minor one, the only significant change was the removal of the older non-accociative min/max function in chapter 5, in favor of recommending a pair of sets of new associative min/max functions.
The next revision is underway as of Auguest 2026.
2. Definitions, etc.
2.1. Original definitions
The rewrite concerns firstly with the following definitions:
Attribute: Known as ''mode'' in the 1985 standard, are implicit parameters affecting the behavior of operations. Informally:
- Rounding attributes/modes concerns how to represent computation results that cannot fit into destination formats.
- Alternate exception handling attributes / trap modes concerns if and how to respond to computation errors.
Block: A 'language-defined syntactic unit for which a user can specify attributes'. which may have varying 'scope' for users to specify attributes for.
Scope: This is an undefined term as of the 2019 revision.
Status Flag: Bi-valued variables that may be 'raised' or 'lowered' (that is, 'cleared' or 'set'). Exceptional conditions in computation can, as side effect, raise status flag(s). Status flags may be retrieved and altered by user.
Now. There are several problems with these definitions:
- Attributes and status flags are associated with blocks for scoping, but the term scope is not defined in the standard; yet chapter 8 later on will discuss the behavior traps to languages with 'scoping' assumptions.
- The definition of 'block' is defered to language standards, which, although familiar to programmers, isn't universal in all languages.
- Some platforms have multiple sets of mode/status flags (e.g. x87 vs SIMD on x86 machines); multi-threaded applications may have mode/status flags that're visible in none but the current thread; some systems may save mode/status flags to make way for other programs and restore them on return.
2.2. A potential rewrite
So, can we find a definition for these terms that're self-contained and purpose-fit for discussion by later chapters? Consider:
Attribute: Associated with subprograms, implicit parameters affacting the behavior of operations. Informally:
- Rounding attributes concerns how to represent computation results that cannot fit into destination formats.
- Alternate exception handling attributes concerns if and how to respond to computation errors.
Notice we've introduced the term 'subprogram', which is essential as we'll see.
Subprogram: A piece of computation that may be reused as an integral unit.
- A subprogram may associate itself with rounding and/or alternate exception handling attributes, as well as status flags; and may alter freely, the said association.
Here, we didn't apply any qualifier to the word 'piece', since the computation may be multi-threaded, may be stopped to make way for others, and thus also, resumed. We also worded it using "may associate itself with" rather than "be associated with", to signify that the association may either be 'static' or 'dynamic', and even optional, as intended in the standard.
So how does the above wording cater to scoping?
First, a subprogram may be defined as a function. In which case, the association of attributes may (statically) begin with the opening brace of a block (typically found in those structural programming languages) and end with the corresponding closing brace.
Secondly, a subprogram may be defined by some kind of 'macro' that 'expands' to a language-defined syntactic unit, fitting the current definition of the standard.
A subprogram is a program in its essence, and _sub_sidiary in its usage. Therefore, the scope certainly can span as large as the "whole" program. Also, as a program, it may be multi-threaded according to the reasonable understanding of any typical programmer. Each individual thread may associate themselves with mode/status flags, like would on a CPU; or a group of threads may associate themselves with shared mode/status flags, like would on a GPU.
When it comes to status flags, a major concern is that, whatever definition we settle on, the flag must not spuriously lower itself. However, there are blocks that don't inherit the flags of its inner scope, most notably the flags raised in a spawned thread don't (typically) get raised in the spawning thread after being joined. Even the problem of the precise definition of this so-called 'spurious' aside, whether to raise the flag upon entering an inner scope is also debated, with terminologies such as "inherit" and "propagate" coming up during discussion.
Scoped association ultimately concerns with 2 operations: push-save, and pop-restore. Push/pop are typically connoted with the call stack of the current thread; save/restore on context switch between active activation records of different threads, processes, or even just co-routines are typically connoted with system-allocated memories.
Status flags are ultimately examined by the user and acted upon. With this being the fundamental concensus, the end-goal seem to be that it must be available to wherever in the program that needs to examine it. Given this, it seems sufficient for languages to make it possible to explicitly preserve the flags wherever it may implicitly discard it. Hence:
Status Flag: Bi-valued variables that may be 'raised' or 'lowered' (that is, 'cleared' or 'set'). Exceptional conditions in computation can, as side effect, raise status flag(s).
3. Floating-point formats
The core of the standard has been to provide data types for carrying out real-valued arithmetic. The formats of these data types are well known, and contents of this chapter are not reiterated.
4. Attributes
As mentioned before, we now talk about attributes using such phrases as: 'subprograms may associate themselves with attributes'. Two major kinds of attributes are discussed, rounding, and alternate exception handling.
Additional attributes new in the 2008 standard include the preferredWidth attribute, value-changing optimization attributes, reproducibility attributes - all of which, concerns the reproducibility of programs.
5. Operations
Providing data type is just half the job, the next half is to define in words that're at least consistent, clear, and unambiguous, exactly the behavior of operations over the data types.
Apart from arithmetic (FP-to-FP), comparision (FP predicates), conversions (from/to-FP), and component manipulation (scaleB, logB, next-up/down, etc.) there also needs operations on the floating point environment, which includes implicit parameters taken by operations (attributes) and implicit side channel that convey non-numerical value information (status flags).
The operations on the floating point environment, 'completes' the picture of a floating point application, in two sense of the word:
- there exist ways for all types of objects to transition between all value states within that type of object.
- there exist ways for all types of objects to influence the value state of each other, all under the control of the user.
6. Infinity, NaNs, and sign bit
NaNs results from erroneous computations. Contrary to the interpretation of some programmers, I personally hold the belief that infinity (signed infinities in particular in IEEE-754) is not a numerical value - rather, it's a limited error recovery mechanism that is able to produce meaningful numerical values under some conditions.
I apply my very same opinion to signed zeros.
7. Exceptions and default exception handling
After discussing the default non-stop exception handling and its behavior, and giving a quick overview to alternate handlings to chapter 8, section 7.1. goes on to discuss the initial setting of flags in newly launched programs (all lowered/cleared), that flags are only lowered by user request, and the various language-feature-specific cases (e.g. when between caller/callee bounderies, block-scope inheritance, etc.) where flags might be raised or lowered.
That's just a summary, and as a matter of copyright, and to save effort in transcribing, we refer interested readers to the published standard text.
As mentioned before, it should be an obvious concensus that status are ultimately to be examined and acted upon, and it need to be available wherever it's needed. So I think most of those "when"s and "whether"s aren't needed as long as language specifications fully specifies the circumstances (i.e. when) those status flags ceases to be available. Hence:
A subprogram may start by either discarding or preserving the status flags of its invoker. After the execution of a subprogram ends, its status flags may also be discarded or preserved. Language standards shall provide means to preserve status flags for examination by still running subprograms.
The standard then goes on to enumerate 5 kinds of exceptional conditions that can occur, synchronously to the operations that produce them.
8. Alternate exception handling attributes.
It's a fact that there are limited thing that can be done in a trap handler. Some of the readers may be aware of the concept of 'async-signal-safety' in POSIX. Signal handlers in their original forms are implemented using hardware traps.
The behavior of the handler must be either completely transparent to the main code, or must terminate the main code in order for the behavior to be well-formed - everything else is literally undefined behavior.
The resuming attributes in the existing section 8.2. are obviouly mostly transparent to the main code. The attributes in existing section 8.3. can be summarized as 2x2 combination of
- immediate (leaves program state undefined) vs delayed (deterministic behavior),
- handler (
try,signal/sigaction) vs transfer (break,throw,goto, etc.).
The problem now, is can we come up with a wording that covers all of the above attributes, while ensuring the premise that the handler is fully programmable, language-agnostic, all with the bonus of possibly covering something we never thought of before? Consider:
Under alternate exception handling, subprograms may be stopped, synchronously to the occurence of exceptional conditions or to the completion of the subprogram, with control transferred to another 'exception handler' subprogram, which may share state, or otherwise communicate with, the just-stopped 'main' subprogram. When the exception handling subprogram ends execution, the control may be transferred back to the main program, or to elsewhere, thereby terminating the 'main' subprogram.
Such handler subprograms may nest, and termination of a handler subprogram by a nested subprogram may even result in the original main subprogram resuming.
Again, the use of the term 'subprogram' avoids the language-specific features such as blocks, return, and makes
9. Recommended operations
What's the significance of operations that're recommended but not required? The answer would be detailed edge-case behavior. Since many recommended operations have many implementation possibilities (precision-related quality, by an ameture or by a professional, etc.) recommending their precise behavior is benefitial for the consistency of applications that depends on them. Which brings us to one of the major goal of the 2008 revision: reproducibility.
10. Expression evaluation
The goal of this chapter in the standard, in my opinion, is two-fold.
First, it needs to allow the operations in the standard to be expressed in ways that fits the design goals and elements of various languages.
For example, operations may need to be spelled out explicitly in assemblies; may be written as formula-like expressions in "system" programming languages; and going higher, map-reduce style idioms.
Second, languages need to specify the mapping, from the semantic of the language, back to the sequence of operations. And the standard needs to place this requirement on languages before they can claim conformance to reproducibility requirements.
Expressions are, by their nature, a feature specific to high-level languages. And the approach taken by the standard in this chapter is overall comprehensive. Although it makes the assumption that computations happen in temporal order, this is fine here, in that the view of expression is a local one.
11. Reproducible floating-point results
One crucial thing to note, is that the reproducibility-related attributes started out from the perspective of 'compilation' of high-level languages. We instead, want to explore how it can cater to 'transpilation' of programs of all kinds, say (hypothetically) from 8086/8087/8088 assembly, to FORTRAN, to C, then to LLVM-IR, then again to WASM and ARM assembly.
Such reproducibility guarantees are however not unconditional.
A similar issue can be seen with the definition of multi-threaded memory model in C/C++, where the behavior of data race is so difficult to fully defined and are inconsistent across platforms, the standard committee chosed to specify the semantic of synchronizations, and declare data races resulting from mis-synchronized memory access as undefined behavior.
This chapter of the standard began with declaring which operations are reproducible, then states:
Programs that can be reliably translated into an explicit or implicit sequence of reproducible operations on reproducible formats produce reproducible results. That is, ... (explanatory texts omitted).
The highlighted elements of interest in this statement:
- ''translated'', which doesn't exclude transpilation in any obvious way.
- ''sequence of reproducible operations'' specify the basis of the form of computations that is reproducible, serving as intermediary for translation.
The negation of the the above statement, that is "programs that cannot be reliably translated into such sequence of ops isn't necessarily unreproducible", although true, is nonetheless irrelevant for standard conformance.
Finally, reprodicibility issues don't disappear even when no floating-point are involved. System configuration and external factors such as network congestion also affect the reproducibility of programs. It's just numerical reproducibility is the easy one to ensure, at least theoretically.