FLT_HAS_SUBNORM is 0: does manually constructed subnormal lead to well-defined behavior when using such subnormal?

0

In case if FLT_HAS_SUBNORM is 0: does manually constructed (using, for example, type punning via union or using memcpy()) subnormal lead to well-defined behavior when such subnormal is used as an input for FP operations (for example, FP comparison)?

Example:

#include <stdio.h>
#include <float.h>
int main( void )
{
    union { unsigned int i; float f; } u = { .i = 1 }; // subnormal
    printf("%d %d %a 0x%08lx\n", FLT_HAS_SUBNORM, u.f != 0.0f, u.f, u.i);
    return 0;
}

Output:

clang: 1 1 0x1p-149 0x00000001

gcc: 1 1 0x1p-149 0x00000001

test compiler: 0 1 0x0p+0 0x00000001

Note: here we see that test compiler does not support %a for subnormals (which is explained by / correlates with FLT_HAS_SUBNORM is 0).

Questions:

  1. Is u.f != 0 here leads to well-defined behavior?
  2. If so, then why C standard permits such manually constructed subnormals (as well as FP operations with such manually constructed subnormals leading to IEEE 754 conformant results) if FLT_HAS_SUBNORM is 0?

UPD. I've read the standard. I'm confused because it says:

FLT_HAS_SUBNORM is 0 means that subnormal numbers are absent (type does not support subnormal numbers)

However, despite of type does not support subnormal numbers in the example above we've seen that it is possible to manually construct subnormals and perform some FP operations on them getting IEEE 754 conformant results.

UPD. In other words: shall the example above (u.f != 0.0f) be interpreted as a violation of FLT_HAS_SUBNORM is 0? If so, then please prove it.

c
ieee-754
asked on Stack Overflow Dec 14, 2020 by pmor • edited Dec 15, 2020 by pmor

1 Answer

2

Is u.f != 0 here leads to well-defined behavior?

No. If subnormal numbers are not supported, then they are not supported regardless of how they are obtained, whether by literals in source code, arithmetic, or manipulation of the bits that represent floating-point objects.

If so, then why C standard permits such manually constructed subnormals…

C is a low-level language and allows direct access to the bytes that represent any object. You can also construct representations of integers that are invalid due to parity errors (on implementations that have such) and representations of char objects that are not in the defined character set. You can also tinker with the bytes of a FILE or a struct tm and produce objects with unsupported values. The fact you can manipulate the bytes does not mean any manipulation of the bytes results in a valid or supported value.

answered on Stack Overflow Dec 14, 2020 by Eric Postpischil

User contributions licensed under CC BY-SA 3.0