is true for the ordered pair of the magnitudes of *x , *y . These functions are fully specified in
IEC 60559. These functions are independent of the current rounding direction mode and raise no
floating-point exceptions, even if *x or *y is a signaling NaN.
Returns
3 The totalordermag functions return nonzero if and only if the total order relation is true for the
ordered pair of the magnitudes of *x , *y .
F.10.13 [Payload functions]
1 IEC 60559 defines the payload to be information contained in a quiet or signaling NaN. The payload
is intended for implementation-defined diagnostic information about the NaN, such as where or
how the NaN was created. The implementation interprets the payload as a nonnegative integer
suitable for use with the functions in this subclause, which get and set payloads. The implementation
may restrict which payloads are admissible for the user to set.
2 NOTE These functions are specified only in Annex F because they depend on details of IEC 60559 formats that might not be
supported if __STDC_IEC_60559_BFP__ is not defined.
F.10.13.1 [The getpayload functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_EXT__
#include <math.h>
#ifdef __STDC_IEC_60559_BFP__
double getpayload(const double *x);
float getpayloadf(const float *x);
long double getpayloadl(const long double *x);
#endif
#ifdef __STDC_IEC_60559_DFP__
_Decimal32 getpayloadd32(const _Decimal32 *x);
_Decimal64 getpayloadd64(const _Decimal64 *x);
_Decimal128 getpayloadd128(const _Decimal128 *x);
#endif
Description
2 The getpayload functions extract the payload of a quiet or signaling NaN input and return it as a
positive-signed floating-point integer. If *x is not a NaN, the return result is −1. These functions
raise no floating-point exceptions, even if *x is a signaling NaN.
Returns
3 The getpayload functions return the payload of the NaN input as a positive-signed floating-point
integer.
F.10.13.2 [The setpayload functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_EXT__
#include <math.h>
#ifdef __STDC_IEC_60559_BFP__
int setpayload(double *res, double pl);
int setpayloadf(float *res, float pl);
int setpayloadl(long double *res, long double pl);
#endif
#ifdef __STDC_IEC_60559_DFP__
int setpayloadd32(_Decimal32 *res, _Decimal32 pl);
int setpayloadd64(_Decimal64 *res, _Decimal64 pl);
int setpayloadd128(_Decimal128 *res, _Decimal128 pl);
#endif
Description
2 The setpayload functions create a quiet NaN with the payload specified by pl and a zero sign bit
and store that NaN in the object pointed to by *res . If pl is not a floating-point integer representing
an admissible payload, *res is set to +0.
Returns
3 If the setpayload functions stored the specified NaN, they return a zero value, otherwise a nonzero
value (and *res is set to +0).
F.10.13.3 [The setpayloadsig functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_EXT__
#include <math.h>
#ifdef __STDC_IEC_60559_BFP__
int setpayloadsig(double *res, double pl);
int setpayloadsigf(float *res, float pl);
int setpayloadsigl(long double *res, long double pl);
#endif
#ifdef __STDC_IEC_60559_DFP__
int setpayloadsigd32(_Decimal32 *res, _Decimal32 pl);
int setpayloadsigd64(_Decimal64 *res, _Decimal64 pl);
int setpayloadsigd128(_Decimal128 *res, _Decimal128 pl);
#endif
Description
2 The setpayloadsig functions create a signaling NaN with the payload specified by pl and a zero
sign bit and store that NaN in the object pointed to by *res . If pl is not a floating-point integer
representing an admissible payload, *res is set to +0.
Returns
3 If the setpayloadsig functions stored the specified NaN, they return a zero value, otherwise a
nonzero value (and *res is set to +0).
F.10.14 [Comparison macros]
1 Relational operators and their corresponding comparison macros (7.12.17) produce equivalent result
values, even if argument values are represented in wider formats. Thus, comparison macro argu-
ments represented in formats wider than their semantic types are not converted to the semantic types,
unless the wide evaluation method converts operands of relational operators to their semantic types.
The standard wide evaluation methods characterized by FLT_EVAL_METHOD and DEC_EVAL_METHOD
equal to 1 or 2 (<IP_ADDRESS>.2, <IP_ADDRESS>.3), do not convert operands of relational operators to their semantic
types.
F.10.14.1 [The iseqsig macro]
1 The equality operator == and the iseqsig macro produce equivalent results, except that the iseqsig
macro raises the "invalid" floating-point exception if an argument is a NaN.
G. [Annex G (normative) IEC 60559-compatible complex arithmetic]
G.1 [Introduction]
1 This annex supplements Annex F to specify complex arithmetic for compatibility with IEC 60559
real floating-point arithmetic. An implementation that defines __STDC_IEC_60559_COMPLEX__ or
__STDC_IEC_559_COMPLEX__ shall conform to the specifications in this annex.[458]
Footnote 458) Implementations that do not define __STDC_IEC_60559_COMPLEX__ or __STDC_IEC_559_COMPLEX__ are not required
to conform to these specifications. The use of __STDC_IEC_559_COMPLEX__ for this purpose is obsolescent and should be
avoided in new code.
G.2 [Types]
1 There is a new keyword _Imaginary , which is used to specify imaginary types. It is used as a type
specifier within declaration specifiers in the same way as _Complex is (thus, _Imaginary float is a
valid type name).
2 There are three imaginary types, designated as float _Imaginary, double _Imaginary, and
long double _Imaginary . The imaginary types (along with the real floating and complex types)
are floating types.
3 For imaginary types, the corresponding real type is given by deleting the keyword _Imaginary
from the type name.
4 Each imaginary type has the same representation and alignment requirements as the corresponding
real type. The value of an object of imaginary type is the value of the real representation times the
imaginary unit.
5 The imaginary type domain comprises the imaginary types.
G.3 [Conventions]
1 A complex or imaginary value with at least one infinite part is regarded as an infinity (even if its
other part is a quiet NaN). A complex or imaginary value is a finite number if each of its parts is a
finite number (neither infinite nor NaN). A complex or imaginary value is a zero if each of its parts is
a zero.
G.4 [Conversions]
G.4.1 [Imaginary types]
1 Conversions among imaginary types follow rules analogous to those for real floating types.
G.4.2 [Real and imaginary]
1 When a value of imaginary type is converted to a real type other than bool,[459] the result is a positive
zero.
Footnote 459) See <IP_ADDRESS>.
2 When a value of real type is converted to an imaginary type, the result is a positive imaginary zero.
G.4.3 [Imaginary and complex]
1 When a value of imaginary type is converted to a complex type, the real part of the complex result
value is a positive zero and the imaginary part of the complex result value is determined by the
conversion rules for the corresponding real types.
2 When a value of complex type is converted to an imaginary type, the real part of the complex value
is discarded and the value of the imaginary part is converted according to the conversion rules for
the corresponding real types.
G.5 [Binary operators]
1 The following subclauses supplement 6.5 in order to specify the type of the result for an operation
with an imaginary operand.
2 For most operand types, the value of the result of a binary operator with an imaginary or complex
operand is completely determined, with reference to real arithmetic, by the usual mathematical
formula. For some operand types, the usual mathematical formula is problematic because of its
treatment of infinities and because of undue overflow or underflow; in these cases the result satisfies
certain properties (specified in G.5.1), but is not completely determined.
G.5.1 [Multiplicative operators]
1 Semantics
If one operand has real type and the other operand has imaginary type, then the result has imaginary
type. If both operands have imaginary type, then the result has real type. (If either operand has
complex type, then the result has complex type.)
2 If the operands are not both complex, then the result and floating-point exception behavior of the *
operator is defined by the usual mathematical formula:
* u iv u + iv
x xu i(xv) (xu) + i(xv)
iy i(yu) (−y)v ((−y)v) + i(yu)
x + iy (xu) + i(yu) ((−y)v) + i(xv)
3 If the second operand is not complex, then the result and floating-point exception behavior of the /
operator is defined by the usual mathematical formula:
/ u iv
x x/u i((−x)/v)
iy i(y/u) y/v
x + iy (x/u) + i(y/u) (y/v) + i((−x)/v)
4 The * and / operators satisfy the following infinity properties for all real, imaginary, and complex
operands:[460]
— if one operand is an infinity and the other operand is a nonzero finite number or an infinity,
then the result of the * operator is an infinity;
— if the first operand is an infinity and the second operand is a finite number, then the result of
the / operator is an infinity;
— if the first operand is a finite number and the second operand is an infinity, then the result of
the / operator is a zero;
— if the first operand is a nonzero finite number or an infinity and the second operand is a zero,
then the result of the / operator is an infinity.
Footnote 460) These properties are already implied for those cases covered in the tables, but are required for all cases (at least where the
state for CX_LIMITED_RANGE is "off").
5 If both operands of the * operator are complex or if the second operand of the / operator is complex,
the operator raises floating-point exceptions if appropriate for the calculation of the parts of the
result, and may raise spurious floating-point exceptions.
6 EXAMPLE 1 Multiplication of double _Complex operands could be implemented as follows. Note that the imaginary unit
I has imaginary type (see G.6).
#include <math.h>
#include <complex.h>
/* Multiply z * w ...*/
double complex _Cmultd(double complex z, double complex w)
{
#pragma STDC FP_CONTRACT OFF
double a, b, c, d, ac, bd, ad, bc, x, y;
a = creal(z); b = cimag(z);
c = creal(w); d = cimag(w);
ac = a * c; bd = b * d;
ad = a * d; bc = b * c;
x = ac - bd; y = ad + bc;
if (isnan(x) && isnan(y)) {
/* Recover infinities that computed as NaN+iNaN ... */
int recalc = 0;
if (isinf(a) || isinf(b)) { // z is infinite
/* "Box" the infinity and change NaNs in the other factor to 0 */
a = copysign(isinf(a) ? 1.0: 0.0, a);
b = copysign(isinf(b) ? 1.0: 0.0, b);
if (isnan(c)) c = copysign(0.0, c);
if (isnan(d)) d = copysign(0.0, d);
recalc = 1;
}
if (isinf(c) || isinf(d)) { // w is infinite
/* "Box" the infinity and change NaNs in the other factor to 0 */
c = copysign(isinf(c) ? 1.0: 0.0, c);
d = copysign(isinf(d) ? 1.0: 0.0, d);
if (isnan(a)) a = copysign(0.0, a);
if (isnan(b)) b = copysign(0.0, b);
recalc = 1;
}
if (!recalc && (isinf(ac) || isinf(bd) ||
isinf(ad) || isinf(bc))) {
/* Recover infinities from overflow by changing NaNs to 0 ... */
if (isnan(a)) a = copysign(0.0, a);
if (isnan(b)) b = copysign(0.0, b);
if (isnan(c)) c = copysign(0.0, c);
if (isnan(d)) d = copysign(0.0, d);
recalc = 1;
}
if (recalc) {
x = INFINITY * (a * c - b * d);
y = INFINITY * (a * d + b * c);
}
}
return x + I * y;
}
7 This implementation achieves the required treatment of infinities at the cost of only one isnan test in ordinary (finite) cases.
It is less than ideal in that undue overflow and underflow could occur.
8 EXAMPLE 2 Division of two double _Complex operands could be implemented as follows.
#include <math.h>
#include <complex.h>
/* Divide z / w ... */
double complex _Cdivd(double complex z, double complex w)
{
#pragma STDC FP_CONTRACT OFF
double a, b, c, d, logbw, denom, x, y;
int ilogbw = 0;
a = creal(z); b = cimag(z);
c = creal(w); d = cimag(w);
logbw = logb(fmaximum_num(fabs(c), fabs(d)));
if (isfinite(logbw)) {
ilogbw = (int)logbw;
c = scalbn(c, -ilogbw); d = scalbn(d, -ilogbw);
}
denom = c * c + d * d;
x = scalbn((a * c + b * d) / denom, -ilogbw);
y = scalbn((b * c - a * d) / denom, -ilogbw);
/* Recover infinities and zeros that computed as NaN+iNaN; */
/* the only cases are nonzero/zero, infinite/finite, and finite/infinite, ... */
if (isnan(x) && isnan(y)) {
if ((denom == 0.0) &&
(!isnan(a) || !isnan(b))) {
x = copysign(INFINITY, c) * a;
y = copysign(INFINITY, c) * b;
}
else if ((isinf(a) || isinf(b)) &&
isfinite(c) && isfinite(d)) {
a = copysign(isinf(a) ? 1.0: 0.0, a);
b = copysign(isinf(b) ? 1.0: 0.0, b);
x = INFINITY * (a * c + b * d);
y = INFINITY * (b * c - a * d);
}
else if ((logbw == INFINITY) &&
isfinite(a) && isfinite(b)) {
c = copysign(isinf(c) ? 1.0: 0.0, c);
d = copysign(isinf(d) ? 1.0: 0.0, d);
x = 0.0 * (a * c + b * d);
y = 0.0 * (b * c - a * d);
}
}
return x + I * y;
}
9 Scaling the denominator alleviates the main overflow and underflow problem, which is more serious than for multiplication.
In the spirit of the multiplication example above, this code does not defend against overflow and underflow in the calculation
of the numerator. Scaling with the scalbn function, instead of with division, provides better roundoff characteristics.
G.5.2 [Additive operators]
1 Semantics
If both operands have imaginary type, then the result has imaginary type. (If one operand has real
type and the other operand has imaginary type, or if either operand has complex type, then the
result has complex type.)
2 In all cases the result and floating-point exception behavior of a + or- operator is defined by the
usual mathematical formula:
+ or- u iv u + iv
x x±u x±iv (x±u)±iv
iy ±u + iy i(y±v) ±u + i(y±v)
x + iy (x±u) + iy x + i(y±v) (x±u) + i(y±v)
G.6 [Complex arithmetic <complex.h>]
1 The macros
imaginary
and
_Imaginary_I
are defined, respectively, as _Imaginary and a constant expression of type float _Imaginary with
the value of the imaginary unit. The macro
I
is defined to be _Imaginary_I (not _Complex_I as stated in 7.3). Notwithstanding the provisions of
7.1.3, a program may undefine and then perhaps redefine the macro imaginary.
2 This subclause contains specifications for the <complex.h> functions that are particularly suited to
IEC 60559 implementations. For families of functions, the specifications apply to all of the functions
even though only the principal function is shown. Unless otherwise specified, where the symbol "±"
occurs in both an argument and the result, the result has the same sign as the argument.
3 The functions are continuous onto both√sides of their branch cuts, taking into account the sign of
zero. For example, csqrt(−2±i0) = ±i 2.
4 Since complex and imaginary values are composed of real values, each function may be regarded as
computing real values from real values. Except as noted, the functions treat real infinities, NaNs,
signed zeros, subnormals, and the floating-point exception flags in a manner consistent with the
specifications for real functions in F.10.[461]
Footnote 461) As noted in G.3, a complex value with at least one infinite part is regarded as an infinity even if its other part is a quiet
NaN.
5 In subsequent subclauses in G.6 "NaN" refers to a quiet NaN. The behavior of signaling NaNs
in Annex G is implementation-defined.
6 The functions cimag, conj, cproj, and creal are fully specified for all implementations, including
IEC 60559 ones, in 7.3.9. These functions raise no floating-point exceptions.
7 Each of the functions cabs and carg is specified by a formula in terms of a real function (whose
special cases are covered in Annex F):
cabs(x + iy ) = hypot(x, y )
carg(x + iy ) = atan2(y , x)
8 Each of the functions casin, catan, ccos, csin, and ctan is specified implicitly by a formula in
terms of other complex functions (whose special cases are specified below):
casin(z ) = −i casinh(iz )
catan(z ) = −i catanh(iz )
ccos(z ) = ccosh(iz )
csin(z ) = −i csinh(iz )
ctan(z ) = −i ctanh(iz )
9 For the other functions, the following subclauses specify behavior for special cases, including
treatment of the "invalid" and "divide-by-zero" floating-point exceptions. For families of functions,
the specifications apply to all of the functions even though only the principal function is shown. For
a function f satisfying f (conj(z)) = conj(f (z)), the specifications for the upper half-plane imply the
specifications for the lower half-plane; if the function f is also either even, f (−z) = f (z), or odd,
f (−z) = −f (z), then the specifications for the first quadrant imply the specifications for the other
three quadrants.
10 In the following subclauses, cis(y) is defined as cos(y) + i sin(y).
G.6.1 [Trigonometric functions]
G.6.1.1 [The cacos functions]
1 — cacos(conj(z)) = conj(cacos(z)).
— cacos(±0 + i0) returns π2 − i0.
— cacos(±0 + iNaN) returns π2 + iNaN.
— cacos(x + i∞) returns π2 − i∞, for finite x.
— cacos(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for nonzero finite x.
— cacos(−∞ + iy) returns pi − i∞, for positive-signed finite y.
— cacos(+∞ + iy) returns +0 − i∞, for positive-signed finite y.
— cacos(−∞ + i∞) returns 3 π4 − i∞.
— cacos(+∞ + i∞) returns π4 − i∞.
— cacos(±∞ + iNaN) returns NaN±i∞ (where the sign of the imaginary part of the result is
unspecified).
— cacos(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite y.
— cacos(NaN + i∞) returns NaN − i∞.
— cacos(NaN + iNaN) returns NaN + iNaN.
G.6.2 [Hyperbolic functions]
G.6.2.1 [The cacosh functions]
1 — cacosh(conj(z)) = conj(cacosh(z)).
— cacosh(±0 + i0) returns +0 + iπ
2 .
— cacosh(x + i∞) returns +∞ + iπ
2 , for finite x.
— cacosh(0 + iNaN) returns NaN± iπ
2 (where the sign of the imaginary part of the result is
unspecified).
— cacosh(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite nonzero x.
— cacosh(−∞ + iy) returns +∞ + iπ, for positive-signed finite y.
— cacosh(+∞ + iy) returns +∞ + i0, for positive-signed finite y.
— cacosh(−∞ + i∞) returns +∞ + i 3π
4 .
— cacosh(+∞ + i∞) returns +∞ + iπ
4 .
— cacosh(±∞ + iNaN) returns +∞ + iNaN.
— cacosh(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite y.
— cacosh(NaN + i∞) returns +∞ + iNaN.
— cacosh(NaN + iNaN) returns NaN + iNaN.
G.6.2.2 [The casinh functions]
1 — casinh(conj(z)) = conj(casinh(z)). and casinh is odd.
— casinh(+0 + i0) returns 0 + i0.
— casinh(x + i∞) returns +∞ + iπ
2 for positive-signed finite x.
— casinh(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite x.
— casinh(+∞ + iy) returns +∞ + i0 for positive-signed finite y.
— casinh(+∞ + i∞) returns +∞ + iπ
4 .
— casinh(+∞ + iNaN) returns +∞ + iNaN.
— casinh(NaN + i0) returns NaN + i0.
— casinh(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite nonzero y.
— casinh(NaN + i∞) returns ±∞ + iNaN (where the sign of the real part of the result is
unspecified).
— casinh(NaN + iNaN) returns NaN + iNaN.
G.6.2.3 [The catanh functions]
1 — catanh(conj(z)) = conj(catanh(z)). and catanh is odd.
— catanh(+0 + i0) returns +0 + i0.
— catanh(+0 + iNaN) returns +0 + iNaN.
— catanh(+1 + i0) returns +∞ + i0 and raises the "divide-by-zero" floating-point exception.
— catanh(x + i∞) returns +0 + iπ
2 , for finite positive-signed x.
— catanh(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for nonzero finite x.
— catanh(+∞ + iy) returns +0 + iπ
2 , for finite positive-signed y.
— catanh(+∞ + i∞) returns +0 + iπ
2 .
— catanh(+∞ + iNaN) returns +0 + iNaN.
— catanh(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite y.
— catanh(NaN + i∞) returns ±0 + iπ
2 (where the sign of the real part of the result is unspecified).
— catanh(NaN + iNaN) returns NaN + iNaN.
G.6.2.4 [The ccosh functions]
1 — ccosh(conj(z)) = conj(ccosh(z)) and ccosh is even.
— ccosh(+0 + i0) returns 1 + i0.
— ccosh(+0 + i∞) returns NaN±i0 (where the sign of the imaginary part of the result is unspec-
ified) and raises the "invalid" floating-point exception.
— ccosh(+0 + iNaN) returns NaN±i0 (where the sign of the imaginary part of the result is
unspecified).
— ccosh(x + i∞) returns NaN + iNaN and raises the "invalid" floating-point exception, for
finite nonzero x.
— ccosh(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite nonzero x.
— ccosh(+∞ + i0) returns +∞ + i0.
— ccosh(+∞ + iy) returns +∞ cis(y), for finite nonzero y.
— ccosh(+∞+i∞) returns ±∞+iNaN (where the sign of the real part of the result is unspecified)
and raises the "invalid" floating-point exception.
— ccosh(+∞ + iNaN) returns +∞ + iNaN.
— ccosh(NaN + i0) returns NaN±i0 (where the sign of the imaginary part of the result is
unspecified).
— ccosh(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for all nonzero numbers y.
— ccosh(NaN + iNaN) returns NaN + iNaN.
G.6.2.5 [The csinh functions]
1 — csinh(conj(z)) = conj(csinh(z)). and csinh is odd.
— csinh(+0 + i0) returns +0 + i0.
— csinh(+0 + i∞) returns ±0 + iNaN (where the sign of the real part of the result is unspecified)
and raises the "invalid" floating-point exception.
— csinh(+0 + iNaN) returns ±0 + iNaN (where the sign of the real part of the result is unspeci-
fied).
— csinh(x + i∞) returns NaN + iNaN and raises the "invalid" floating-point exception, for
positive finite x.
— csinh(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite nonzero x.
— csinh(+∞ + i0) returns +∞ + i0.
— csinh(+∞ + iy) returns +∞ cis(y), for positive finite y.
— csinh(+∞+i∞) returns ±∞+iNaN (where the sign of the real part of the result is unspecified)
and raises the "invalid" floating-point exception.
— csinh(+∞ + iNaN) returns ±∞ + iNaN (where the sign of the real part of the result is
unspecified).
— csinh(NaN + i0) returns NaN + i0.
— csinh(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for all nonzero numbers y.
— csinh(NaN + iNaN) returns NaN + iNaN.
G.6.2.6 [The ctanh functions]
1 — ctanh(conj(z)) = conj(ctanh(z)) and ctanh is odd.
— ctanh(+0 + i0) returns +0 + i0.
— ctanh(0 + i∞) returns 0 + iNaN and raises the "invalid" floating-point exception.
— ctanh(x + i∞) returns NaN + iNaN and raises the "invalid" floating-point exception, for
finite nonzero x.
— ctanh(0 + iNaN) returns 0 + iNaN.
— ctanh(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite nonzero x.
— ctanh(+∞ + iy) returns 1 + i0sin(2y), for positive-signed finite y.
— ctanh(+∞ + i∞) returns 1±i0 (where the sign of the imaginary part of the result is unspeci-
fied).
— ctanh(+∞ + iNaN) returns 1±i0 (where the sign of the imaginary part of the result is unspec-
ified).
— ctanh(NaN + i0) returns NaN + i0.
— ctanh(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for all nonzero numbers y.
— ctanh(NaN + iNaN) returns NaN + iNaN.
G.6.3 [Exponential and logarithmic functions]
G.6.3.1 [The cexp functions]
1 — cexp(conj(z)) = conj(cexp(z)).
— cexp(±0 + i0) returns 1 + i0.
— cexp(x + i∞) returns NaN + iNaN and raises the "invalid" floating-point exception, for finite
x.
— cexp(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point excep-
tion, for finite x.
— cexp(+∞ + i0) returns +∞ + i0.
— cexp(−∞ + iy) returns +0 cis(y), for finite y.
— cexp(+∞ + iy) returns +∞ cis(y), for finite nonzero y.
— cexp(−∞ + i∞) returns ±0±i0 (where the signs of the real and imaginary parts of the result
are unspecified).
— cexp(+∞ + i∞) returns ±∞ + iNaN and raises the "invalid" floating-point exception (where
the sign of the real part of the result is unspecified).
— cexp(−∞ + iNaN) returns ±0±i0 (where the signs of the real and imaginary parts of the result
are unspecified).
— cexp(+∞ + iNaN) returns ±∞ + iNaN (where the sign of the real part of the result is unspec-
ified).
— cexp(NaN + i0) returns NaN + i0.
— cexp(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point excep-
tion, for all nonzero numbers y.
— cexp(NaN + iNaN) returns NaN + iNaN.
G.6.3.2 [The clog functions]
1 — clog(conj(z)) = conj(clog(z)).
— clog(−0 + i0) returns −∞ + iπ and raises the "divide-by-zero" floating-point exception.
— clog(+0 + i0) returns −∞ + i0 and raises the "divide-by-zero" floating-point exception.
— clog(x + i∞) returns +∞ + iπ
2 , for finite x.
— clog(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point excep-
tion, for finite x.
— clog(−∞ + iy) returns +∞ + iπ, for finite positive-signed y.
— clog(+∞ + iy) returns +∞ + i0, for finite positive-signed y.
— clog(−∞ + i∞) returns +∞ + i 3π
4 .
— clog(+∞ + i∞) returns +∞ + iπ
4 .
— clog(±∞ + iNaN) returns +∞ + iNaN.
— clog(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point excep-
tion, for finite y.
— clog(NaN + i∞) returns +∞ + iNaN.
— clog(NaN + iNaN) returns NaN + iNaN.
G.6.4 [Power and absolute-value functions]
G.6.4.1 [The cpow functions]
1 The cpow functions raise floating-point exceptions if appropriate for the calculation of the parts of
the result, and may also raise spurious floating-point exceptions.[462]
Footnote 462) This allows cpow(z, c) to be implemented as cexp(cclog(z)) without precluding implementations that treat special cases
more carefully.
G.6.4.2 [The csqrt functions]
1 — csqrt(conj(z)) = conj(csqrt(z)).
— csqrt(±0 + i0) returns +0 + i0.
— csqrt(x + i∞) returns +∞ + i∞, for all x (including NaN).
— csqrt(x + iNaN) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite x.
— csqrt(−∞ + iy) returns +0 + i∞, for finite positive-signed y.
— csqrt(+∞ + iy) returns +∞ + i0, for finite positive-signed y.
— csqrt(−∞ + iNaN) returns NaN±i∞ (where the sign of the imaginary part of the result is
unspecified).
— csqrt(+∞ + iNaN) returns +∞ + iNaN.
— csqrt(NaN + iy) returns NaN + iNaN and optionally raises the "invalid" floating-point
exception, for finite y.
— csqrt(NaN + iNaN) returns NaN + iNaN.
G.7 [Type-generic math <tgmath.h>]
1 Type-generic macros that accept complex arguments also accept imaginary arguments. If an argu-
ment is imaginary, the macro expands to an expression whose type is real, imaginary, or complex, as
appropriate for the particular function: if the argument is imaginary, then the types of cos, cosh,
fabs, carg, cimag, and creal are real; the types of sin, tan, sinh, tanh, asin, atan, asinh, and
atanh are imaginary; and the types of the others are complex.
2 Given an imaginary argument, each of the type-generic macros cos, sin, tan, cosh, sinh, tanh,
asin, atan, asinh, atanh is specified by a formula in terms of real functions:
cos(iy ) = cosh(y )
sin(iy ) = i sinh(y )
tan(iy ) = i tanh(y )
cosh(iy ) = cos(y )
sinh(iy ) = i sin(y )
tanh(iy ) = i tan(y )
asin(iy ) = i asinh(y )
atan(iy ) = i atanh(y )
asinh(iy ) = i asin(y )
atanh(iy ) = i atan(y )
H. [Annex H (normative) IEC 60559 interchange and extended types]
H.1 [Introduction]
1 This annex specifies extension types for programming language C that have the arithmetic inter-
change and extended floating-point formats specified in ISO/IEC/IEEE 60559. This annex also
includes functions that support the non-arithmetic interchange formats in that standard. This annex
was adapted from ISO/IEC TS 18661-3:2015, Floating-point extensions for C —Interchange and
extended types.
2 An implementation that defines __STDC_IEC_60559_TYPES__ to 202311L shall conform to the
specifications in this annex. An implementation may define __STDC_IEC_60559_TYPES__ only
if it defines __STDC_IEC_60559_BFP__ , indicating support for IEC 60559 binary floating-point
arithmetic, or defines __STDC_IEC_60559_DFP__ , indicating support for IEC 60559 decimal floating-
point arithmetic (or defines both). Where a binding between the C language and IEC 60559 is
indicated, the IEC 60559-specified behavior is adopted by reference, unless stated otherwise.
H.2 [Types]
This clause specifies types that support IEC 60559 arithmetic interchange and extended formats. The
encoding conversion functions (H.11.3) and numeric conversion functions for encodings (H.12.3,
and H.12.4) support the non-arithmetic interchange formats specified in IEC 60559.
H.2.1 [Interchange floating types]
1 IEC 60559 specifies interchange formats, and their encodings, which can be used for the exchange of
floating-point data between implementations. These formats are identified by their radix (binary
or decimal) and their storage width N. The two tables below give the C floating-point model
parameters[463] (<IP_ADDRESS>.2) for the IEC 60559 interchange formats, where the function round() rounds
to the nearest integer.
Binary interchange format parameters
Parameter binary16 binary32 binary64 binary128 binaryN (N ≥ 128)
N , storage width in bits 16 32 64 128 N, a multiple of 32
p, precision in bits 11 24 53 113 N − round(4 × log2 (N )) + 13
emax , maximum exponent e 16 128 1024 16384 2(N −p−1)
emin , minimum exponent e −13 −125 −1021 −16381 3 − emax
Decimal interchange format parameters
Parameter decimal32 decimal64 decimal128 decimalN (N ≥ 32)
N , storage width in bits 32 64 128 N, a multiple of 32
p, precision in bits 7 16 34 9 × (N ÷ 32) − 2
emax , maximum exponent e 97 385 6145 3 × 2((N ÷16)+3) + 1
emin , minimum exponent e −94 −382 −6142 3 − emax
EXAMPLE For the binary160 format, p = 144, emax = 32678 and emin = −32765. For the decimal160 format, p = 43,
emax = 24577 and emin = −24574.
Footnote 463) In IEC 60559, normal floating-point numbers are expressed with the first significant digit to the left of the radix point.
Hence the exponent in the C model (shown in the tables) is 1 more than the exponent of the same number in the IEC 60559
model.
2 Types designated:
_FloatN
where N is 16, 32, 64, or ≥ 128 and a multiple of 32; and, types designated
_DecimalN
where N ≥ 32 and a multiple of 32, are collectively called the interchange floating types. Each
interchange floating type has the IEC 60559 interchange format corresponding to its width (N ) and
radix (2 for _FloatN, 10 for _DecimalN). Each interchange floating type is not compatible with any
other type.
3 An implementation that defines __STDC_IEC_60559_BFP__ and __STDC_IEC_60559_TYPES__ shall
provide _Float32 and _Float64 as interchange floating types with the same representation and
alignment requirements as float and double, respectively. If the implementation’s long double
type supports an IEC 60559 interchange format of width N > 64, then the implementation shall also
provide the type _FloatN as an interchange floating type with the same representation and alignment
requirements as long double. The implementation may provide other radix-2 interchange floating
types _FloatN; the set of such types supported is implementation-defined.
4 An implementation that defines __STDC_IEC_60559_DFP__ provides the decimal floating
types _Decimal32 , _Decimal64 , and _Decimal128 (6.2.5). If the implementation also defines
__STDC_IEC_60559_TYPES__ , it may provide other radix-10 interchange floating types _DecimalN;
the set of such types supported is implementation-defined.
H.2.2 [Non-arithmetic interchange formats]
1 An implementation supports IEC 60559 non-arithmetic interchange formats by providing the as-
sociated encoding-to-encoding conversion functions (H.11.3.2) in <math.h> and the string-from-
encoding functions (H.12.3) and string-to-encodng functions (H.12.4) in <stdlib.h>.
2 An implementation that defines __STDC_IEC_60559_BFP__ and __STDC_IEC_60559_TYPES__ sup-
ports some IEC 60559 radix-2 interchange formats as arithmetic formats by providing types _Float
N (as well as float and double) with those formats. The implementation may support other
IEC 60559 radix-2 interchange formats as non-arithmetic formats; the set of such formats supported
is implementation-defined.
3 An implementation that defines __STDC_IEC_60559_DFP__ and __STDC_IEC_60559_TYPES__ sup-
ports some IEC 60559 radix-10 interchange formats as arithmetic formats by providing types
_DecimalN with those formats. The implementations may support other IEC 60559 radix-10 inter-
change formats as non-arithmetic formats; the set of such formats supported is implementation-
defined.
H.2.3 [Extended floating types]
1 For each of its basic formats, IEC 60559 specifies an extended format whose maximum exponent and
precision exceed those of the basic format it is associated with. Extended formats are intended for
arithmetic with more precision and exponent range than is available in the basic formats used for
the input data. The extra precision and range often mitigate round-off error and eliminate overflow
and underflow in intermediate computations. The table below gives the minimum values of these
parameters, as defined for the C floating-point model (<IP_ADDRESS>.2). For all IEC 60559 extended (and
interchange) formats, emin = 3 − emax .
Extended format parameters for floating-point numbers
Extended formats associated with:
Parameter binary32 binary64 binary128 decimal64 decimal128
p digits ≥ 32 64 128 22 40
emax ≥ 1024 16384 65536 6145 24577
2 Types designated _Float32x , _Float64x , _Float128x , _Decimal64x , and _Decimal128x support
the corresponding IEC 60559 extended formats and are collectively called the extended floating
types. The set of values of _Float32x is a subset of the set of values of _Float64x ; the set
of values of _Float64x is a subset of the set of values of _Float128x . The set of values of
_Decimal64x is a subset of the set of values of _Decimal128x . Each extended floating type is
not compatible with any other type. An implementation that defines __STDC_IEC_60559_BFP__
and __STDC_IEC_60559_TYPES__ shall provide _Float32x , and may provide one or both of the
types _Float64x and _Float128x . An implementation that defines __STDC_IEC_60559_DFP__ and
__STDC_IEC_60559_TYPES__ shall provide _Decimal64x , and may provide _Decimal128x . Which
(if any) of the optional extended floating types are provided is implementation-defined.
3 NOTE IEC 60559 does not specify an extended format associated with the decimal32 format, nor does this annex specify an
extended type associated with the _Decimal32 type.
4 NOTE The _Float32x type may have the same format as double. The _Decimal64x type may have the same format as
_Decimal128 .
H.2.4 [Classification of real floating types]
1 6.2.5 defines standard floating types as a collective name for the types float, double and
long double and it defines decimal floating types as a collective name for the types _Decimal32 ,
_Decimal64 , and _Decimal128 .
2 H.2.1 defines interchange floating types and H.2.3 defines extended floating types.
3 The types _FloatN and _FloatNx are collectively called binary floating types.
4 This subclause broadens decimal floating types to include the types _DecimalN and _DecimalNx,
introduced in this annex, as well as _Decimal32 , _Decimal64 , and _Decimal128 .
5 This sublcause broadens real floating types to include all interchange floating types and extended
floating types, as well as standard floating types.
6 Thus, in this annex, real floating types are classified as follows:
— standard floating types, composed of float, double, long double;
— decimal floating types, composed of _DecimalN, _DecimalNx;
— binary floating types, composed of _FloatN, _FloatNx;
— interchange floating types, composed of _FloatN, _DecimalN; and,
— extended floating types, composed of _FloatNx, _DecimalNx.
7 NOTE Standard floating types (which have an implementation-defined radix) are not included in either binary floating
types (which always have radix 2) or decimal floating types (which always have radix 10).
H.2.5 [Complex types]
1 This subclause broadens the C complex types (6.2.5) to also include similar types whose correspond-
ing real parts have binary floating types. For the types _FloatN and _FloatNx, there are complex
types designated respectively as _FloatN _Complex and _FloatNx _Complex . (Complex types are a
conditional feature that implementations need not support; see <IP_ADDRESS>.)
H.2.6 [Imaginary types]
1 This subclause broadens the C imaginary types (G.2) to also include similar types whose correspond-
ing real parts have binary floating types. For the types _FloatN and _FloatNx, there are imaginary
types designated respectively as _FloatN _Imaginary and _FloatNx _Imaginary . The imaginary
types (along with the real floating and complex types) are floating types. (Annex G, including
imaginary types, is a conditional feature that implementations need not support; see <IP_ADDRESS>.)
H.3 [Characteristics in <float.h>]
1 This subclause enhances the FLT_EVAL_METHOD and DEC_EVAL_METHOD macros to apply to the types
introduced in this annex.
2 If FLT_RADIX is 2, the value of FLT_EVAL_METHOD (<IP_ADDRESS>.2) characterizes the use of evaluation
formats for standard floating types and for binary floating types:
-1 indeterminable;
0 evaluate all operations and constants, whose semantic type comprises a set of values
that is a strict subset of the values of float, to the range and precision of float; evaluate
all other operations and constants to the range and precision of the semantic type;
1 evaluate operations and constants, whose semantic type comprises a set of values that
is a strict subset of the values of double, to the range and precision of double; evaluate
all other operations and constants to the range and precision of the semantic type;
2 evaluate operations and constants, whose semantic type comprises a set of values that is
a strict subset of the values of long double, to the range and precision of long double;
evaluate all other operations and constants to the range and precision of the semantic
type;
N where _FloatN is a supported interchange floating type, evaluate operations and con-
stants, whose semantic type comprises a set of values that is a strict subset of the values
of _FloatN, to the range and precision of _FloatN; evaluate all other operations and
constants to the range and precision of the semantic type;
N +1 where _FloatNx is a supported extended floating type, evaluate operations and con-
stants, whose semantic type comprises a set of values that is a strict subset of the values
of _FloatNx, to the range and precision of _FloatNx; evaluate all other operations and
constants to the range and precision of the semantic type.
If FLT_RADIX is not 2, the use of evaluation formats for operations and constants of binary floating
types is implementation-defined.
3 The implementation-defined value of DEC_EVAL_METHOD (<IP_ADDRESS>.3) characterizes the use of evalua-
tion formats for decimal floating types:
-1 indeterminable;
0 evaluate all operations and constants just to the range and precision of the type;
1 evaluate operations and constants, whose semantic type comprises a set of values that
is a strict subset of the values of _Decimal64 , to the range and precision of _Decimal64 ;
evaluate all other operations and constants to the range and precision of the semantic
type;
2 evaluate operations and constants, whose semantic type comprises a set of values that is
a strict subset of the values of _Decimal128 , to the range and precision of _Decimal128 ;
evaluate all other operations and constants to the range and precision of the semantic
type;
N where _DecimalN is a supported interchange floating type evaluate operations and
constants, whose semantic type comprises a set of values that is a strict subset of
the values of _DecimalN, to the range and precision of _DecimalN; evaluate all other
operations and constants to the range and precision of the semantic type;
N +1 where _DecimalNx is a supported extended floating type evaluate operations and
constants, whose semantic type comprises a set of values that is a strict subset of the
values of _DecimalNx, to the range and precision of _DecimalNx; evaluate all other
operations and constants to the range and precision of the semantic type.
4 This subclause also specifies <float.h> macros, analogous to the macros for standard floating
types, that characterize binary floating types in terms of the model presented in <IP_ADDRESS>.2. This
subclause generalizes the specification of characteristics in <IP_ADDRESS>.3 to include the decimal floating
types introduced in this annex. The prefix FLTN_ indicates the type _FloatN or the non-arithmetic
binary interchange format of width N . The prefix FLTNX_ indicates the type _FloatNx. The prefix
DECN_ indicates the type _DecimalN or the non-arithmetic decimal interchange format of width
N . The prefix DECNX_ indicates the type _DecimalNx. The type parameters p, emax , and emin for
extended floating types are for the extended floating type itself, not for the basic format that it
extends.
5 If __STDC_WANT_IEC_60559_TYPES_EXT__ is defined (by the user) at the point in the code where
<float.h> is first included, the following applies (H.8). For each interchange or extended floating
type that the implementation provides, <float.h> shall define the associated macros in the fol-
lowing lists. Conversely, for each such type that the implementation does not provide, <float.h>
shall not define the associated macros in the following list, except, the implementation shall define
the macros FLTN_DECIMAL_DIG and FLTN_DIG if it supports the IEC 60559 non-arithmetic binary
interchange format of width N (H.2.2).
6 The signaling NaN macros
The macro
FLTN_SNAN
DECN_SNAN
FLTNX_SNAN
DECNX_SNAN
expand to constant expressions of types _FloatN, _DecimalN, _FloatNx, and _DecimalNx respec-
tively, representing a signaling NaN. If an optional unary + or- operator followed by a signaling
NaN macro is used for initializing an object of the same type that has static or thread storage
duration, the object is initialized with a signaling NaN value.
7 The integer values given in the following lists shall be replaced by integer constant expressions:
— radix of exponent representation, b (2 for binary, 10 for decimal)
For the standard floating types, this value is implementation-defined and is specified
by the macro FLT_RADIX. For the interchange and extended floating types there is no
corresponding macro; the radix is an inherent property of the types.
— The number of bits in the floating-point significand, p
FLTN_MANT_DIG
FLTNX_MANT_DIG
— The number of digits in the coefficient, p
DECN_MANT_DIG
DECNX_MANT_DIG
— number of decimal digits, n, such that any floating-point number with p bits can be rounded
to a floating-point number with n decimal digits and back again without change to the value,
⌈1 + p log10 (2)⌉
FLTN_DECIMAL_DIG
FLTNX_DECIMAL_DIG
— number of decimal digits, q, such that any floating-point number with q decimal digits can
be rounded to a floating-point number with p bits and back again without a change to the q
decimal digits, ⌊(p − 1) log10 (2)⌋
FLTN_DIG
FLTNX_DIG
— minimum negative integer such that the radix raised to one less than that power is a normalized
floating-point number, emin
FLTN_MIN_EXP
FLTNX_MIN_EXP
DECN_MIN_EXP
DECNX_MIN_EXP
— minimum negative integer such that 10 raised to that power is in the range of normalized
floating-point numbers, ⌈ log10 (2)emin −1 ⌉
FLTN_MIN_10_EXP
FLTNX_MIN_10_EXP
— maximum negative integer such that the radix raised to one less than that power is a repre-
sentable finite floating-point number, emax
FLTN_MAX_EXP
FLTNX_MAX_EXP
DECN_MAX_EXP
DECNX_MAX_EXP
— maximum integer such that 10 raised to that power is in the range of representable finite
floating-point numbers, ⌊ log10 ((1 − 2−p )2emax )⌋
FLTN_MAX_10_EXP
FLTNX_MAX_10_EXP
— maximum representable finite floating-pointer number, (1 − b−p )bemax
FLTN_MAX
FLTNX_MAX
DECN_MAX
DECNX_MAX
— the difference between 1 and the least value greater than 1 that is representable in the given
floating-point type, b1−p
FLTN_EPSILON
FLTNX_EPSILON
DECN_EPSILON
DECNX_EPSILON
— minimum normalized positive floating-point number, bemin −1
FLTN_MIN
FLTNX_MIN
DECN_MIN
DECNX_MIN
— minimum positive floating-point number, bemin −p
FLTN_TRUE_MIN
FLTNX_TRUE_MIN
DECN_TRUE_MIN
DECNX_TRUE_MIN
H.4 [Conversions]
1 This subclause enhances the usual arithmetic conversions (<IP_ADDRESS>) to handle interchange and ex-
tended floating types. It supports the IEC 60559 recommendation against allowing implicit conver-
sions of operands to obtain a common type where the conversion is between types where neither is
a subset of (or equivalent to) the other.
2 This subclause also broadens the operation binding in F.3 for the IEC 60559 convertFormat operation
to apply to IEC 60559 arithmetic and non-arithmetic formats.
H.4.1 [Real floating and integer]
1 When a finite value of interchange or extended floating type is converted to an integer type other
than bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of
the integral part cannot be represented by the integer type, the "invalid" floating-point exception
shall be raised and the result of the conversion is unspecified.
2 When a value of integer type is converted to an interchange or extended floating type, if the value
being converted can be represented exactly in the new type, it is unchanged. If the value being
converted cannot be represented exactly, the result shall be correctly rounded with exceptions raised
as specified in IEC 60559.
H.4.2 [Usual arithmetic conversions]
1 If either operand is of floating type, the common real type is determined as follows:
— If one operand has decimal floating type, the other operand shall not have standard floating
type, binary floating type, complex type, or imaginary type.
— If only one operand has a floating type, the other operand is converted to the corresponding
real type of the operand of floating type.
— If both operands have the same corresponding real type, no further conversion is needed.
— If both operands have floating types and neither of the sets of values of their corresponding
real types is a subset of (or equivalent to) the other, the behavior is undefined.
— Otherwise, if both operands are floating types and the sets of values of their corresponding
real types are not equivalent, the operand whose set of values of its corresponding real type
is a strict subset of the set of values of the corresponding real type of the other operand is
converted, without change of type domain, to a type with the corresponding real type of that
other operand.
— Otherwise, if both operands are floating types and the sets of values of their corresponding
real types are equivalent, then the following rules are applied:
– If the corresponding real type of either operand is an interchange floating type, the other
operand is converted, without change of type domain, to a type whose corresponding
real type is that same interchange floating type.
– Otherwise, if the corresponding real type of either operand is long double, the other
operand is converted, without change of type domain, to a type whose corresponding
real type is long double.
– Otherwise, if the corresponding real type of either operand is double, the other operand
is converted, without change of type domain, to a type whose corresponding real type is
double[464] .
– Otherwise, if the corresponding real type of either operand is _Float128x or
_Decimal128x , the other operand is converted, without change of type domain, to a type
whose corresponding real type is _Float128x or _Decimal128x , respectively.
– Otherwise, if the corresponding real type of either operand is _Float64x or _Decimal64x ,
the other operand is converted, without change of type domain, to a type whose corre-
sponding real type is _Float64x or _Decimal64x , respectively.
Footnote 464) All cases where float might have the same format as another type are covered above.
H.4.3 [Arithmetic and non-arithmetic formats]
1 The operation binding in F.3 for the IEC 60559 convertFormat operation applies to IEC 60559
arithmetic and non-arithmetic formats as follows:
— For conversions between arithmetic formats supported by floating types (same or different
radix) – casts and implicit conversions.
— For same-radix conversions between non-arithmetic interchange formats – encoding-to-
encoding conversion functions (H.11.3.2).
— For conversions between non-arithmetic interchange formats (same or different radix) – compo-
sitions of string-from-encoding functions (H.12.3) (converting exactly) and string-to-encoding
functions (H.12.4).
— For same-radix conversions from interchange formats supported by interchange floating types
to non-arithmetic interchange formats – compositions of encode functions (H.<IP_ADDRESS>, <IP_ADDRESS>,
<IP_ADDRESS>) and encoding-to-encoding functions (H.11.3.2).
— For same radix conversions from non-arithmetic interchange formats to interchange formats
supported by interchange floating types – compositions of encoding-to-encoding conversion
functions (H.11.3.2) and decode functions (H.<IP_ADDRESS>, <IP_ADDRESS>, <IP_ADDRESS>). See the example in
H.<IP_ADDRESS>.
— For conversions from non-arithmetic interchange formats to arithmetic formats supported
by floating types (same or different radix) – compositions of string-from-encoding functions
(H.12.3) (converting exactly) and numeric conversion functions strtod, etc. (<IP_ADDRESS>, <IP_ADDRESS>).
See the example in H.12.2.
— For conversions from arithmetic formats supported by floating types to non-arithmetic in-
terchange formats (same or different radix) – compositions of numeric conversion func-
tions strfromd, etc. (<IP_ADDRESS>, <IP_ADDRESS>) (converting exactly) and string-to-encoding functions
(H.12.4).
H.5 [Lexical Elements]
H.5.1 [Keywords]
1 This subclause expands the list of keywords (6.4.1) to also include:
— _FloatN, where N is 16, 32, 64, or ≥ 128 and a multiple of 32
— _Float32x
— _Float64x
— _Float128x
— _DecimalN, where N is 96 or > 128 and a multiple of 32
— _Decimal64x
— _Decimal128x
H.5.2 [Constants]
1 This subclause specifies constants of interchange and extended floating types.
2 This subclause expands floating-suffix (<IP_ADDRESS>) to also include: fN, FN, fNx, FNx, dN, DN, dNx, or DNx.
3 A floating suffix dN, DN, dNx, or DNx shall not be used in a hexadecimal-floating-constant.
4 A floating suffix shall not designate a type that the implementation does not provide.
5 If a floating constant is suffixed by fN or FN, it has type _FloatN. If suffixed by fNx or FNx, it has
type _FloatNx. If suffixed by dN or DN, it has type _DecimalN. If suffixed by dNx or DNx, it has type
_DecimalNx .
6 The quantum exponent of a floating constant of decimal floating type is the same as for the result
value of the corresponding strtodN or strtodNx function (H.12.2) for the same numeric string.
7 NOTE For N = 32, 64, and 128, the suffixes dN and DN in this subclause for constants of type _DecimalN are equivalent
alternatives to the suffixes df, dd, dl, DF, DD, and DL in <IP_ADDRESS> for the same types.
H.6 [Expressions]
1 This subclause expands the specification of expressions to also cover interchange and extended
floating types.
2 Operators involving operands of interchange or extended floating type are evaluated according to
the semantics of IEC 60559, including production of decimal floating-point results with the preferred
quantum exponent as specified in IEC 60559 (see <IP_ADDRESS>.3).
3 For multiplicative operators (6.5.5), additive operators (6.5.6), relational operators (6.5.8), equality
operators (6.5.9), and compound assignment operators (<IP_ADDRESS>), if either operand has decimal
floating type, the other operand shall not have standard floating type, binary floating type, complex
type, or imaginary type.
4 For conditional operators (6.5.15), if the second or third operand has decimal floating type, the
other of those operands shall not have standard floating type, binary floating type, complex type, or
imaginary type.
5 The equivalence of expressions noted in F.9.2 apply to expressions of binary floating types, as well
as standard floating types.
H.7 [Declarations]
1 This subclause expands the list of type specifiers (6.7.2) to also include:
— _FloatN, where N is 16, 32, 64, or ≥ 128 and a multiple of 32
— _Float32x
— _Float64x
— _Float128x
— _DecimalN, where N is 96 or > 128 and a multiple of 32
— _Decimal64x
— _Decimal128x
2 The type specifiers _FloatN (where N is 16, 32, 64, or ≥ 128 and a multiple of 32), _Float32x ,
_Float64x , _Float128x , _DecimalN (where N is 96 or > 128 and a multiple of 32), _Decimal64x ,
and _Decimal128x shall not be used if the implementation does not support the corresponding
types (see <IP_ADDRESS> and H.2).
3 This subclause also expands the list under Constraints in 6.7.2 to also include:
— _FloatN, where N is 16, 32, 64, or ≥ 128 and a multiple of 32
— _Float32x
— _Float64x
— _Float128x
— _DecimalN, where N is 96 or > 128 and a multiple of 32
— _Decimal64x
— _Decimal128x
— _FloatN _Complex , where N is 16, 32, 64, or ≥ 128 and a multiple of 32
— _Float32x _Complex
— _Float64x _Complex
— _Float128x _Complex
H.8 [Identifiers in standard headers]
1 The identifiers added to library headers by this annex are defined or declared by their respective
headers only if the macro __STDC_WANT_IEC_60559_TYPES_EXT__ is defined (by the user) at the
point in the code where the appropriate header is first included.
H.9 [Complex arithmetic <complex.h>]
1 This subclause specifies complex functions for corresponding real types that are binary floating
types.
2 Each function synopsis in 7.3 specifies a family of functions including a principal function with
one or more double complex parameters and a double complex or double return value. This
subclause expands the synopsis to also include other functions, with the same name as the principal
function but with fN and fNx suffixes, which are corresponding functions whose parameters and
return values have corresponding real types _FloatN and _FloatNx.
3 The following function prototypes are added to the synopses of the respective subclauses in 7.3.
For each binary floating type that the implementation provides, <complex.h> shall declare the
associated functions (see H.8). Conversely, for each such type that the implementation does not
provide, <complex.h> shall not declare the associated functions.
(7.3.5) Trigonometric functions
_FloatN complex cacosfN(_FloatN complex z);
_FloatNx complex cacosfNx(_FloatNx complex z);
_FloatN complex casinfN(_FloatN complex z);
_FloatNx complex casinfNx(_FloatNx complex z);
_FloatN complex catanfN(_FloatN complex z);
_FloatNx complex catanfNx(_FloatNx complex z);
_FloatN complex ccosfN(_FloatN complex z);
_FloatNx complex ccosfNx(_FloatNx complex z);
_FloatN complex csinfN(_FloatN complex z);
_FloatNx complex csinfNx(_FloatNx complex z);
_FloatN complex ctanfN(_FloatN complex z);
_FloatNx complex ctanfNx(_FloatNx complex z);
(7.3.6) Hyperbolic functions
_FloatN complex cacoshfN(_FloatN complex z);
_FloatNx complex cacoshfNx(_FloatNx complex z);
_FloatN complex casinhfN(_FloatN complex z);
_FloatNx complex casinhfNx(_FloatNx complex z);
_FloatN complex catanhfN(_FloatN complex z);
_FloatNx complex catanhfNx(_FloatNx complex z);
_FloatN complex ccoshfN(_FloatN complex z);
_FloatNx complex ccoshfNx(_FloatNx complex z);
_FloatN complex csinhfN(_FloatN complex z);
_FloatNx complex csinhfNx(_FloatNx complex z);
_FloatN complex ctanhfN(_FloatN complex z);
_FloatNx complex ctanhfNx(_FloatNx complex z);
(7.3.7) Exponential and logarithmic functions
_FloatN complex cexpfN(_FloatN complex z);
_FloatNx complex cexpfNx(_FloatNx complex z);
_FloatN complex clogfN(_FloatN complex z);
_FloatNx complex clogfNx(_FloatNx complex z);
(7.3.8) Power and absolute value functions
_FloatN cabsfN(_FloatN complex z);
_FloatNx cabsfNx(_FloatNx complex z);
_FloatN complex cpowfN(_FloatN complex x, _FloatN complex y);
_FloatNx complex cpowfNx(_FloatNx complex x, _FloatNx complex y);
_FloatN complex csqrtfN(_FloatN complex z);
_FloatNx complex csqrtfNx(_FloatNx complex z);
(7.3.9) Manipulation functions
_FloatN cargfN(_FloatN complex z);
_FloatNx cargfNx(_FloatNx complex z);
_FloatN cimagfN(_FloatN complex z);
_FloatNx cimagfNx(_FloatNx complex z);
_FloatN complex CMPLXFN(_FloatN x, _FloatN y);
_FloatNx complex CMPLXFNX(_FloatNx x, _FloatNx y);
_FloatN complex conjfN(_FloatN complex z);
_FloatNx complex conjfNx(_FloatNx complex z);
_FloatN complex cprojfN(_FloatN complex z);
_FloatNx complex cprojfNx(_FloatNx complex z);
_FloatN crealfN(_FloatN complex z);
_FloatNx crealfNx(_FloatNx complex z);
4 For the functions listed in "future library directions" for <complex.h> (7.33.1), the possible suffixes
are expanded to also include fN and fNx.
H.10 [Floating-point environment]
1 This subclause broadens the effects of the floating-point environment (7.6) to apply to types and
formats specified in this annex.
2 The same floating-point status flags are used by floating-point operations for all floating types,
including those types introduced in this annex, and by conversions for IEC 60559 non-arithmetic
interchange formats.
3 Both the dynamic rounding direction mode accessed by fegetround and fesetround and the
FENV_ROUND rounding control pragma apply to operations for binary floating types, as well as
for standard floating types, and also to conversions for radix-2 non-arithmetic interchange for-
mats. Likewise, both the dynamic rounding direction mode accessed by fe_dec_getround and
fe_dec_setround and the FENV_DEC_ROUND rounding control pragmas apply to operations for all
the decimal floating types, including those decimal floating types introduced in this annex, and to
conversions for radix-10 non-arithmetic interchange formats.
4 In 7.6.2, the table of functions affected by constant rounding modes for standard floating types
applies also for binary floating types. Each <math.h> function family listed in the table indicates
the family of functions of all standard and binary floating types (for example, the acos family
includes acosf, acosl, acosfN, and acosfNx as well as acos). The fMencfN, strfromencfN, and
strtoencfN functions are also affected by these constant rounding modes.
5 In 7.6.3, in the table of functions affected by constant rounding modes for decimal floating types, each
<math.h> function family indicates the family of functions of all decimal floating types (for example,
the acos family includes acosdN and acosdNx). The dMencbindN, dMencdecdN, strfromencbindN,
strfromencdecdN, strtoencbindN, and strtoencdecdN functions are also affected by these con-
stant rounding modes.
H.11 [Mathematics <math.h>]
1 This subclause specifies types, functions, and macros for interchange and extended floating types,
generally corresponding to those specified in 7.12 and F.10.
2 All classification macros (7.12.3) and comparison macros (7.12.17) naturally extend to handle inter-
change and extended floating types. For comparison macros, if neither of the sets of values of the
argument formats is a subset of (or equivalent to) the other, the behavior is undefined.
3 This subclause also specifies encoding conversion functions that are part of support for the non-
arithmetic interchange formats in IEC 60559 (see H.2.2).
4 Most function synopses in 7.12 specify a family of functions including a principal function with
one or more double parameters, a double return value, or both. The synopses are expanded to
also include functions with the same name as the principal function but with fN, fNx, dN, and dNx
suffixes, which are corresponding functions whose parameters, return values, or both are of types
_FloatN, _FloatNx , _DecimalN, and _DecimalNx, respectively.
5 For each interchange or extended floating type that the implementation provides, <math.h> shall
define the associated types and macros and declare the associated functions (see H.8). Conversely, for
each such type that the implementation does not provide, <math.h> shall not define the associated
types and macros or declare the associated functions unless explicitly specified otherwise.
6 With the types
float_t
double_t
in 7.12 are included the type
long_double_t
and for each supported type _FloatN, the type
_FloatN_t
and for each supported type _DecimalN , the type
_DecimalN_t
These are floating types, such that:
— each of the types has at least the range and precision of the corresponding real floating type;
— long_double_t has at least the range and precision of double_t;
— _FloatN_t
has at least the range and precision of _FloatM_t if N > M ;
— _DecimalN_t
has at least the range and precision of _DecimalM_t if N > M .
If FLT_RADIX is 2 and FLT_EVAL_METHOD (H.3) is nonnegative, then each of the types corresponding
to a standard or binary floating type is the type whose range and precision are specified by
FLT_EVAL_METHOD to be used for evaluating operations and constants of that standard or binary
floating type. If DEC_EVAL_METHOD (H.3) is nonnegative, then each of the types corresponding to a
decimal floating type is the type whose range and precision are specified by DEC_EVAL_METHOD to
be used for evaluating operations and constants of that decimal floating type.
7 EXAMPLE If the supported standard and binary floating types are
Type IEC 60559 format
_Float16 binary16
float, _Float32 binary32
double, _Float64 , _Float32x binary64
long double, _Float64x 80-bit binary64-extended
_Float128 binary128
then the following tables gives the types with _t suffixes for various values for a FLT_EVAL_METHOD of a given value m:
_t type/m 0 1 2 32
_Float16_t float double long double _Float32
float_t float double long double float
_Float32_t _Float32 double long double _Float32
double_t double double long double double
_Float64_t _Float64 _Float64 long double _Float64
long_double_t long double long double long double long double
_Float128_t _Float128 _Float128 _Float128 _Float128
_t type/m 64 128 33 65
_Float16_t _Float64 _Float128 _Float32x _Float64x
float_t _Float64 _Float128 _Float32x _Float64x
_Float32_t _Float64 _Float128 _Float32x _Float64x
double_t double _Float128 double _Float64x
_Float64_t _Float64 _Float128 _Float64 _Float64x
long_double_t long double _Float128 long double long double
_Float128_t _Float128 _Float128 _Float128 _Float128
H.11.1 [Macros]
1 This subclause adds macros in 7.12 as follows.
2 The macros
HUGE_VAL_FN
HUGE_VAL_DN
HUGE_VAL_FNX
HUGE_VAL_DNX
expand to constant expressions of types _FloatN, _DecimalN, _FloatNx, and _DecimalNx, respec-
tively, representing positive infinity.
3 The macros
FP_FAST_FMAFN
FP_FAST_FMADN
FP_FAST_FMAFNX
FP_FAST_FMADNX
are, respectively, _FloatN, _DecimalN, _FloatNx, and _DecimalNx analogues of FP_FAST_FMA.
4 The macros in the following lists are interchange and extended floating type analogues of
FP_FAST_FADD, FP_FAST_FADDL, FP_FAST_DADDL, etc.
5 For M < N , the macros
FP_FAST_FMADDFN
FP_FAST_FMSUBFN
FP_FAST_FMMULFN
FP_FAST_FMDIVFN
FP_FAST_FMFMAFN
FP_FAST_FMSQRTFN
FP_FAST_DMADDDN
FP_FAST_DMSUBDN
FP_FAST_DMMULDN
FP_FAST_DMDIVDN
FP_FAST_DMFMADN
FP_FAST_DMSQRTDN
characterize the corresponding functions whose arguments are of an interchange floating type of
width N and whose return type is an interchange floating type of width M .
6 For M ≤ N , the macros
FP_FAST_FMADDFNX
FP_FAST_FMSUBFNX
FP_FAST_FMMULFNX
FP_FAST_FMDIVFNX
FP_FAST_FMFMAFNX
FP_FAST_FMSQRTFNX
FP_FAST_DMADDDNX
FP_FAST_DMSUBDNX
FP_FAST_DMMULDNX
FP_FAST_DMDIVDNX
FP_FAST_DMFMADNX
FP_FAST_DMSQRTDNX
characterize the corresponding functions whose arguments are of an extended floating type that
extends a format of width N and whose return type is an interchange floating type of width M .
7 For M < N , the macros
FP_FAST_FMXADDFN
FP_FAST_FMXSUBFN
FP_FAST_FMXMULFN
FP_FAST_FMXDIVFN
FP_FAST_FMXFMAFN
FP_FAST_FMXSQRTFN
FP_FAST_DMXADDDN
FP_FAST_DMXSUBDN
FP_FAST_DMXMULDN
FP_FAST_DMXDIVDN
FP_FAST_DMXFMADN
FP_FAST_DMXSQRTDN
characterize the corresponding functions whose arguments are of an interchange floating type of
width N and whose return type is an extended floating type that extends a format of width M .
8 For M < N , the macros
FP_FAST_FMXADDFNX
FP_FAST_FMXSUBFNX
FP_FAST_FMXMULFNX
FP_FAST_FMXDIVFNX
FP_FAST_FMXFMAFNX
FP_FAST_FMXSQRTFNX
FP_FAST_DMXADDDNX
FP_FAST_DMXSUBDNX
FP_FAST_DMXMULDNX
FP_FAST_DMXDIVDNX
FP_FAST_DMXFMADNX
FP_FAST_DMXSQRTDNX
characterize the corresponding functions whose arguments are of an extended floating type that
extends a format of width N and whose return type is an extended floating type that extends a
format of width M .
H.11.2 [Functions]
1 This sublause adds the following functions to the synopses of the respective subclauses in 7.12.
(7.12.4) Trigonometric functions
_FloatN acosfN(_FloatN x);
_FloatNx acosfNx(_FloatNx x);
_DecimalN acosdN(_DecimalN x);
_DecimalNx acosdNx(_DecimalNx x);
_FloatN asinfN(_FloatN x);
_FloatNx asinfNx(_FloatNx x);
_DecimalN asindN(_DecimalN x);
_DecimalNx asindNx(_DecimalNx x);
_FloatN atanfN(_FloatN x);
_FloatNx atanfNx(_FloatNx x);
_DecimalN atandN(_DecimalN x);
_DecimalNx atandNx(_DecimalNx x);
_FloatN atan2fN(_FloatN y, _FloatN x);
_FloatNx atan2fNx(_FloatNx y, _FloatNx x);
_DecimalN atan2dN(_DecimalN y, _DecimalN x);
_DecimalNx atan2dNx(_DecimalNx y, _DecimalNx x);
_FloatN cosfN(_FloatN x);
_FloatNx cosfNx(_FloatNx x);
_DecimalN cosdN(_DecimalN x);
_DecimalNx cosdNx(_DecimalNx x);
_FloatN sinfN(_FloatN x);
_FloatNx sinfNx(_FloatNx x);
_DecimalN sindN(_DecimalN x);
_DecimalNx sindNx(_DecimalNx x);
_FloatN tanfN(_FloatN x);
_FloatNx tanfNx(_FloatNx x);
_DecimalN tandN(_DecimalN x);
_DecimalNx tandNx(_DecimalNx x);
_FloatN acospifN(_FloatN x);
_FloatNx acospifNx(_FloatNx x);
_DecimalN acospidN(_DecimalN x);
_DecimalNx acospidNx(_DecimalNx x);
_FloatN asinpifN(_FloatN x);
_FloatNx asinpifNx(_FloatNx x);
_DecimalN asinpidN(_DecimalN x);
_DecimalNx asinpidNx(_DecimalNx x);
_FloatN atanpifN(_FloatN x);
_FloatNx atanpifNx(_FloatNx x);
_DecimalN atanpidN(_DecimalN x);
_DecimalNx atanpidNx(_DecimalNx x);
_FloatN atan2pifN(_FloatN y, _FloatN x);
_FloatNx atan2pifNx(_FloatNx y, _FloatNx x);
_DecimalN atan2pidN(_DecimalN y, _DecimalN x);
_DecimalNx atan2pidNx(_DecimalNx y, _DecimalNx x);
_FloatN cospifN(_FloatN x);
_FloatNx cospifNx(_FloatNx x);
_DecimalN cospidN(_DecimalN x);
_DecimalNx cospidNx(_DecimalNx x);
_FloatN sinpifN(_FloatN x);
_FloatNx sinpifNx(_FloatNx x);
_DecimalN sinpidN(_DecimalN x);
_DecimalNx sinpidNx(_DecimalNx x);
_FloatN tanpifN(_FloatN x);
_FloatNx tanpifNx(_FloatNx x);
_DecimalN tanpidN(_DecimalN x);
_DecimalNx tanpidNx(_DecimalNx x);
(7.12.5) Hyperbolic functions
_FloatN acoshfN(_FloatN x);
_FloatNx acoshfNx(_FloatNx x);
_DecimalN acoshdN(_DecimalN x);
_DecimalNx acoshdNx(_DecimalNx x);
_FloatN asinhfN(_FloatN x);
_FloatNx asinhfNx(_FloatNx x);
_DecimalN asinhdN(_DecimalN x);
_DecimalNx asinhdNx(_DecimalNx x);
_FloatN atanhfN(_FloatN x);
_FloatNx atanhfNx(_FloatNx x);
_DecimalN atanhdN(_DecimalN x);
_DecimalNx atanhdNx(_DecimalNx x);
_FloatN coshfN(_FloatN x);
_FloatNx coshfNx(_FloatNx x);
_DecimalN coshdN(_DecimalN x);
_DecimalNx coshdNx(_DecimalNx x);
_FloatN sinhfN(_FloatN x);
_FloatNx sinhfNx(_FloatNx x);
_DecimalN sinhdN(_DecimalN x);
_DecimalNx sinhdNx(_DecimalNx x);
_FloatN tanhfN(_FloatN x);
_FloatNx tanhfNx(_FloatNx x);
_DecimalN tanhdN(_DecimalN x);
_DecimalNx tanhdNx(_DecimalNx x);
(7.12.6) Exponential and logarithmic functions
_FloatN expfN(_FloatN x);
_FloatNx expfNx(_FloatNx x);
_DecimalN expdN(_DecimalN x);
_DecimalNx expdNx(_DecimalNx x);
_FloatN exp10fN(_FloatN x);
_FloatNx exp10fNx(_FloatNx x);
_DecimalN exp10dN(_DecimalN x);
_DecimalNx exp10dNx(_DecimalNx x);
_FloatN exp10m1fN(_FloatN x);
_FloatNx exp10m1fNx(_FloatNx x);
_DecimalN exp10m1dN(_DecimalN x);
_DecimalNx exp10m1dNx(_DecimalNx x);
_FloatN exp2fN(_FloatN x);
_FloatNx exp2fNx(_FloatNx x);
_DecimalN exp2dN(_DecimalN x);
_DecimalNx exp2dNx(_DecimalNx x);
_FloatN exp2m1fN(_FloatN x);
_FloatNx exp2m1fNx(_FloatNx x);
_DecimalN exp2m1dN(_DecimalN x);
_DecimalNx exp2m1dNx(_DecimalNx x);
_FloatN expm1fN(_FloatN x);
_FloatNx expm1fNx(_FloatNx x);
_DecimalN expm1dN(_DecimalN x);
_DecimalNx expm1dNx(_DecimalNx x);
_FloatN frexpfN(_FloatN value, int *exp);
_FloatNx frexpfNx(_FloatNx value, int *exp);
_DecimalN frexpdN(_DecimalN value, int *exp);
_DecimalNx frexpdNx(_DecimalNx value, int *exp);
int ilogbfN(_FloatN x);
int ilogbfNx(_FloatNx x);
int ilogbdN(_DecimalNx x);
int ilogbdNx(_DecimalNx x);
_FloatN ldexpfN(_FloatN value, int exp);
_FloatNx ldexpfNx(_FloatNx value, int exp);
_DecimalN ldexpdN(_DecimalN value, int exp);
_DecimalNx ldexpdNx(_DecimalNx value, int exp);
long int llogbfN(_FloatN x);
long int llogbfNx(_FloatNx x);
long int llogbdN(_DecimalN x);
long int llogbdNx(_DecimalNx x);
_FloatN logfN(_FloatN x);
_FloatNx logfNx(_FloatNx x);
_DecimalN logdN(_DecimalN x);
_DecimalNx logdNx(_DecimalNx x);
_FloatN log10fN(_FloatN x);
_FloatNx log10fNx(_FloatNx x);
_DecimalN log10dN(_DecimalN x);
_DecimalNx log10dNx(_DecimalNx x);
_FloatN log10p1fN(_FloatN x);
_FloatNx log10p1fNx(_FloatNx x);
_DecimalN log10p1dN(_DecimalN x);
_DecimalNx log10p1dNx(_DecimalNx x);
_FloatN log1pfN(_FloatN x);
_FloatNx log1pfNx(_FloatNx x);
_FloatN logp1fN(_FloatN x);
_FloatNx logp1fNx(_FloatNx x);
_DecimalN log1pdN(_DecimalN x);
_DecimalNx log1pdNx(_DecimalNx x);
_DecimalN logp1dN(_DecimalN x);
_DecimalNx logp1dNx(_DecimalNx x);
_FloatN log2fN(_FloatN x);
_FloatNx log2fNx(_FloatNx x);
_DecimalN log2dN(_DecimalN x);
_DecimalNx log2dNx(_DecimalNx x);
_FloatN log2p1fN(_FloatN x);
_FloatNx log2p1fNx(_FloatNx x);
_DecimalN log2p1dN(_DecimalN x);
_DecimalNx log2p1dNx(_DecimalNx x);
_FloatN logbfN(_FloatN x);
_FloatNx logbfNx(_FloatNx x);
_DecimalN logbdN(_DecimalN x);
_DecimalNx logbdNx(_DecimalNx x);
_FloatN modffN(_FloatN x, _FloatN *iptr);
_FloatNx modffNx(_FloatNx x, _FloatNx *iptr);
_DecimalN modfdN(_DecimalN x, _DecimalN *iptr);
_DecimalNx modfdNx(_DecimalNx x, _DecimalNx *iptr);
_FloatN scalbnfN(_FloatN value, int exp);
_FloatNx scalbnfNx(_FloatNx value, int exp);
_DecimalN scalbndN(_DecimalN value, int exp);
_DecimalNx scalbndNx(_DecimalNx value, int exp);
_FloatN scalblnfN(_FloatN value, long int exp);
_FloatNx scalblnfNx(_FloatNx value, long int exp);
_DecimalN scalblndN(_DecimalN value, long int exp);
_DecimalNx scalblndNx(_DecimalNx value, long int exp);
(7.12.7) Power and absolute-value functions
_FloatN cbrtfN(_FloatN x);
_FloatNx cbrtfNx(_FloatNx x);
_DecimalN cbrtdN(_DecimalN x);
_DecimalNx cbrtdNx(_DecimalNx x);
_FloatN compoundnfN(_FloatN x, long long int n);
_FloatNx compoundnfNx(_FloatNx x, long long int n);
_DecimalN compoundndN(_DecimalN x, long long int n);
_DecimalNx compoundndNx(_DecimalNx x, long long int n);
_FloatN fabsfN(_FloatN x);
_FloatNx fabsfNx(_FloatNx x);
_DecimalN fabsdN(_DecimalN x);
_DecimalNx fabsdNx(_DecimalNx x);
_FloatN hypotfN(_FloatN x, _FloatN y);
_FloatNx hypotfNx(_FloatNx x, _FloatNx y);
_DecimalN hypotdN(_DecimalN x, _DecimalN y);
_DecimalNx hypotdNx(_DecimalNx x, _DecimalNx y);
_FloatN powfN(_FloatN x, _FloatN y);
_FloatNx powfNx(_FloatNx x, _FloatNx y);
_DecimalN powdN(_DecimalN x, _DecimalN y);
_DecimalNx powdNx(_DecimalNx x, _DecimalNx y);
_FloatN pownfN(_FloatN x, long long int n);
_FloatNx pownfNx(_FloatNx x, long long int n);
_DecimalN powndN(_DecimalN x, long long int n);
_DecimalNx powndNx(_DecimalNx x, long long int n);
_FloatN powrfN(_FloatN x, _FloatN y);
_FloatNx powrfNx(_FloatNx x, _FloatNx y);
_DecimalN powrdN(_DecimalN x, _DecimalN y);
_DecimalNx powrdNx(_DecimalNx x, _DecimalNx y);
_FloatN rootnfN(_FloatN x, long long int n);
_FloatNx rootnfNx(_FloatNx x, long long int n);
_DecimalN rootndN(_DecimalN x, long long int n);
_DecimalNx rootndNx(_DecimalNx x, long long int n);
_FloatN rsqrtfN(_FloatN x);
_FloatNx rsqrtfNx(_FloatNx x);
_DecimalN rsqrtdN(_DecimalN x);
_DecimalNx rsqrtdNx(_DecimalNx x);
_FloatN sqrtfN(_FloatN x);
_FloatNx sqrtfNx(_FloatNx x);
_DecimalN sqrtdN(_DecimalN x);
_DecimalNx sqrtdNx(_DecimalNx x);
(7.12.8) Error and gamma functions
_FloatN erffN(_FloatN x);
_FloatNx erffNx(_FloatNx x);
_DecimalN erfdN(_DecimalN x);
_DecimalNx erfdNx(_DecimalNx x);
_FloatN erfcfN(_FloatN x);
_FloatNx erfcfNx(_FloatNx x);
_DecimalN erfcdN(_DecimalN x);
_DecimalNx erfcdNx(_DecimalNx x);
_FloatN lgammafN(_FloatN x);
_FloatNx lgammafNx(_FloatNx x);
_DecimalN lgammadN(_DecimalN x);
_DecimalNx lgammadNx(_DecimalNx x);
_FloatN tgammafN(_FloatN x);
_FloatNx tgammafNx(_FloatNx x);
_DecimalN tgammadN(_DecimalN x);
_DecimalNx tgammadNx(_DecimalNx x);
(7.12.9) Nearest integer functions
_FloatN ceilfN(_FloatN x);
_FloatNx ceilfNx(_FloatNx x);
_DecimalN ceildN(_DecimalN x);
_DecimalNx ceildNx(_DecimalNx x);
_FloatN floorfN(_FloatN x);
_FloatNx floorfNx(_FloatNx x);
_DecimalN floordN(_DecimalN x);
_DecimalNx floordNx(_DecimalNx x);
_FloatN nearbyintfN(_FloatN x);
_FloatNx nearbyintfNx(_FloatNx x);
_DecimalN nearbyintdN(_DecimalN x);
_DecimalNx nearbyintdNx(_DecimalNx x);
_FloatN rintfN(_FloatN x);
_FloatNx rintfNx(_FloatNx x);
_DecimalN rintdN(_DecimalN x);
_DecimalNx rintdNx(_DecimalNx x);
long int lrintfN(_FloatN x);
long int lrintfNx(_FloatNx x);
long int lrintdN(_DecimalN x);
long int lrintdNx(_DecimalNx x);
long long int llrintfN(_FloatN x);
long long int llrintfNx(_FloatNx x);
long long int llrintdN(_DecimalN x);
long long int llrintdNx(_DecimalNx x);
_FloatN roundfN(_FloatN x);
_FloatNx roundfNx(_FloatNx x);
_DecimalN rounddN(_DecimalN x);
_DecimalNx rounddNx(_DecimalNx x);
long int lroundfN(_FloatN x);
long int lroundfNx(_FloatNx x);
long int lrounddN(_DecimalN x);
long int lrounddNx(_DecimalNx x);
long long int llroundfN(_FloatN x);
long long int llroundfNx(_FloatNx x);
long long int llrounddN(_DecimalN x);
long long int llrounddNx(_DecimalNx x);
_FloatN roundevenfN(_FloatN x);
_FloatNx roundevenfNx(_FloatNx x);
_DecimalN roundevendN(_DecimalN x);
_DecimalNx roundevendNx(_DecimalNx x);
_FloatN truncfN(_FloatN x);
_FloatNx truncfNx(_FloatNx x);
_DecimalN truncdN(_DecimalN x);
_DecimalNx truncdNx(_DecimalNx x);
_FloatN fromfpfN(_FloatN x, int rnd, unsigned int width);
_FloatNx fromfpfNx(_FloatNx x, int rnd, unsigned int width);
_DecimalN fromfpdN(_DecimalN x, int rnd, unsigned int width);
_DecimalNx fromfpdNx(_DecimalNx x, int rnd, unsigned int width);
_FloatN ufromfpfN(_FloatN x, int rnd, unsigned int width);
_FloatNx ufromfpfNx(_FloatNx x, int rnd, unsigned int width);
_DecimalN ufromfpdN(_DecimalN x, int rnd, unsigned int width);
_DecimalNx ufromfpdNx(_DecimalNx x, int rnd, unsigned int width);
_FloatN fromfpxfN(_FloatN x, int rnd, unsigned int width);
_FloatNx fromfpxfNx(_FloatNx x, int rnd, unsigned int width);
_DecimalN fromfpxdN(_DecimalN x, int rnd, unsigned int width);
_DecimalNx fromfpxdNx(_DecimalNx x, int rnd, unsigned int width);
_FloatN ufromfpxfN(_FloatN x, int rnd, unsigned int width);
_FloatNx ufromfpxfNx(_FloatNx x, int rnd, unsigned int width);
_DecimalN ufromfpxdN(_DecimalN x, int rnd, unsigned int width);
_DecimalNx ufromfpxdNx(_DecimalNx x, int rnd, unsigned int width);
(<IP_ADDRESS>) Remainder functions
_FloatN fmodfN(_FloatN x, _FloatN y);
_FloatNx fmodfNx(_FloatNx x, _FloatNx y);
_DecimalN fmoddN(_DecimalN x, _DecimalN y);
_DecimalNx fmoddNx(_DecimalNx x, _DecimalNx y);
_FloatN remainderfN(_FloatN x, _FloatN y);
_FloatNx remainderfNx(_FloatNx x, _FloatNx y);
_DecimalN remainderdN(_DecimalN x, _DecimalN y);
_DecimalNx remainderdNx(_DecimalNx x, _DecimalNx y);
_FloatN remquofN(_FloatN x, _FloatN y, int *quo);
_FloatNx remquofNx(_FloatNx x, _FloatNx y, int *quo);
(7.12.11) Manipulation functions
_FloatN copysignfN(_FloatN x, _FloatN y);
_FloatNx copysignfNx(_FloatNx x, _FloatNx y);
_DecimalN copysigndN(_DecimalN x, _DecimalN y);
_DecimalNx copysigndNx(_DecimalNx x, _DecimalNx y);
_FloatN nanfN(const char *tagp);
_FloatNx nanfNx(const char *tagp);
_DecimalN nandN(const char *tagp);
_DecimalNx nandNx(const char *tagp);
_FloatN nextafterfN(_FloatN x, _FloatN y);
_FloatNx nextafterfNx(_FloatNx x, _FloatNx y);
_DecimalN nextafterdN(_DecimalN x, _DecimalN y);
_DecimalNx nextafterdNx(_DecimalNx x, _DecimalNx y);
_FloatN nextupfN(_FloatN x);
_FloatNx nextupfNx(_FloatNx x);
_DecimalN nextupdN(_DecimalN x);
_DecimalNx nextupdNx(_DecimalNx x);
_FloatN nextdownfN(_FloatN x);
_FloatNx nextdownfNx(_FloatNx x);
_DecimalN nextdowndN(_DecimalN x);
_DecimalNx nextdowndNx(_DecimalNx x);
int canonicalizefN(_FloatN * cx, const _FloatN * x);
int canonicalizefNx(_FloatNx * cx, const _FloatNx * x);
int canonicalizedN(_DecimalN * cx, const _DecimalN * x);
int canonicalizedNx(_DecimalNx * cx, const _DecimalNx * x);
(7.12.12) Maximum, minimum, and positive difference functions
_FloatN fdimfN(_FloatN x, _FloatN y);
_FloatNx fdimfNx(_FloatNx x, _FloatNx y);
_DecimalN fdimdN(_DecimalN x, _DecimalN y);
_DecimalNx fdimdNx(_DecimalNx x, _DecimalNx y);
_FloatN fmaximumfN(_FloatN x, _FloatN y);
_FloatNx fmaximumfNx(_FloatNx x, _FloatNx y);
_DecimalN fmaximumdN(_DecimalN x, _DecimalN y);
_DecimalNx fmaximumdNx(_DecimalNx x, _DecimalNx y);
_FloatN fminimumfN(_FloatN x, _FloatN y);
_FloatNx fminimumfNx(_FloatNx x, _FloatNx y);
_DecimalN fminimumdN(_DecimalN x, _DecimalN y);
_DecimalNx fminimumdNx(_DecimalNx x, _DecimalNx y);
_FloatN fmaximum_magfN(_FloatN x, _FloatN y);
_FloatNx fmaximum_magfNx(_FloatNx x, _FloatNx y);
_DecimalN fmaximum_magdN(_DecimalN x, _DecimalN y);
_DecimalNx fmaximum_magdNx(_DecimalNx x, _DecimalNx y);
_FloatN fminimum_magfN(_FloatN x, _FloatN y);
_FloatNx fminimum_magfNx(_FloatNx x, _FloatNx y);
_DecimalN fminimum_magdN(_DecimalN x, _DecimalN y);
_DecimalNx fminimum_magdNx(_DecimalNx x, _DecimalNx y);
_FloatN fmaximum_numfN(_FloatN x, _FloatN y);
_FloatNx fmaximum_numfNx(_FloatNx x, _FloatNx y);
_DecimalN fmaximum_numdN(_DecimalN x, _DecimalN y);
_DecimalNx fmaximum_numdNx(_DecimalNx x, _DecimalNx y);
_FloatN fminimum_numfN(_FloatN x, _FloatN y);
_FloatNx fminimum_numfNx(_FloatNx x, _FloatNx y);
_DecimalN fminimum_numdN(_DecimalN x, _DecimalN y);
_DecimalNx fminimum_numdNx(_DecimalNx x, _DecimalNx y);
_FloatN fmaximum_mag_numfN(_FloatN x, _FloatN y);
_FloatNx fmaximum_mag_numfNx(_FloatNx x, _FloatNx y);
_DecimalN fmaximum_mag_numdN(_DecimalN x, _DecimalN y);
_DecimalNx fmaximum_mag_numdNx(_DecimalNx x, _DecimalNx y);
_FloatN fminimum_mag_numfN(_FloatN x, _FloatN y);
_FloatNx fminimum_mag_numfNx(_FloatNx x, _FloatNx y);
_DecimalN fminimum_mag_numdN(_DecimalN x, _DecimalN y);
_DecimalNx fminimum_mag_numdNx(_DecimalNx x, _DecimalNx y);
(<IP_ADDRESS>) Fused multiply-add
_FloatN fmafN(_FloatN x, _FloatN y, _FloatN z);
_FloatNx fmafNx(_FloatNx x, _FloatNx y, _FloatNx z);
_DecimalN fmadN(_DecimalN x, _DecimalN y, _DecimalN z);
_DecimalNx fmadNx(_DecimalNx x, _DecimalNx y, _DecimalNx z);
(7.12.14) Functions that round result to narrower type
_FloatM fMaddfN(_FloatN x, _FloatN y); // M < N
_FloatM fMaddfNx(_FloatNx x, _FloatNx y); // M ≤ N
_FloatMx fMxaddfN(_FloatN x, _FloatN y); // M < N
_FloatMx fMxaddfNx(_FloatNx x, _FloatNx y); // M < N
_DecimalM dMadddN(_DecimalN x, _DecimalN y); // M < N
_DecimalM dMadddNx(_DecimalNx x, _DecimalNx y); // M ≤ N
_DecimalMx dMxadddN(_DecimalN x, _DecimalN y); // M < N
_DecimalMx dMxadddNx(_DecimalNx x, _DecimalNx y); // M < N
_FloatM fMsubfN(_FloatN x, _FloatN y); // M < N
_FloatM fMsubfNx(_FloatNx x, _FloatNx y); // M ≤ N
_FloatMx fMxsubfN(_FloatN x, _FloatN y); // M < N
_FloatMx fMxsubfNx(_FloatNx x, _FloatNx y); // M < N
_DecimalM dMsubdN(_DecimalN x, _DecimalN y); // M < N
_DecimalM dMsubdNx(_DecimalNx x, _DecimalNx y); // M ≤ N
_DecimalMx dMxsubdN(_DecimalN x, _DecimalN y); // M < N
_DecimalMx dMxsubdNx(_DecimalNx x, _DecimalNx y); // M < N
_FloatM fMmulfN(_FloatN x, _FloatN y); // M < N
_FloatM fMmulfNx(_FloatNx x, _FloatNx y); // M ≤ N
_FloatMx fMxmulfN(_FloatN x, _FloatN y); // M < N
_FloatMx fMxmulfNx(_FloatNx x, _FloatNx y); // M < N
_DecimalM dMmuldN(_DecimalN x, _DecimalN y); // M < N
_DecimalM dMmuldNx(_DecimalNx x, _DecimalNx y); // M ≤ N
_DecimalMx dMxmuldN(_DecimalN x, _DecimalN y); // M < N
_DecimalMx dMxmuldNx(_DecimalNx x, _DecimalNx y); // M < N
_FloatM fMdivfN(_FloatN x, _FloatN y); // M < N
_FloatM fMdivfNx(_FloatNx x, _FloatNx y); // M ≤ N
_FloatMx fMxdivfN(_FloatN x, _FloatN y); // M < N
_FloatMx fMxdivfNx(_FloatNx x, _FloatNx y); // M < N
_DecimalM dMdivdN(_DecimalN x, _DecimalN y); // M < N
_DecimalM dMdivdNx(_DecimalNx x, _DecimalNx y); // M ≤ N
_DecimalMx dMxdivdN(_DecimalN x, _DecimalN y); // M < N
_DecimalMx dMxdivdNx(_DecimalNx x, _DecimalNx y); // M < N
_FloatM fMfmafN(_FloatN x, _FloatN y, _FloatN z); // M < N
_FloatM fMfmafNx(_FloatNx x, _FloatNx y, _FloatNx z); // M ≤ N
_FloatMx fMxfmafN(_FloatN x, _FloatN y, _FloatN z); // M < N
_FloatMx fMxfmafNx(_FloatNx x, _FloatNx y, _FloatNx z); // M < N
_DecimalM dMfmadN(_DecimalN x, _DecimalN y, _DecimalN z); // M < N
_DecimalM dMfmadNx(_DecimalNx x, _DecimalNx y, _DecimalNx z); // M ≤ N
_DecimalMx dMxfmadN(_DecimalN x, _DecimalN y, _DecimalN z); // M < N
_DecimalMx dMxfmadNx(_DecimalNx x, _DecimalNx y, _DecimalNx z); // M < N
_FloatM fMsqrtfN(_FloatN x); // M < N
_FloatM fMsqrtfNx(_FloatNx x); // M ≤ N
_FloatMx fMxsqrtfN(_FloatN x); // M < N
_FloatMx fMxsqrtfNx(_FloatNx x); // M < N
_DecimalM dMsqrtdN(_DecimalN x); // M < N
_DecimalM dMsqrtdNx(_DecimalNx x); // M ≤ N
_DecimalMx dMxsqrtdN(_DecimalN x); // M < N
_DecimalMx dMxsqrtdNx(_DecimalNx x); // M < N
(7.12.15) Quantum and quantum exponent functions
_DecimalN quantizedN(_DecimalN x, _DecimalN y);
_DecimalNx quantizedNx(_DecimalNx x, _DecimalNx y);
bool samequantumdN(_DecimalN x, _DecimalN y);
bool samequantumdNx(_DecimalNx x, _DecimalNx y);
_DecimalN quantumdN(_DecimalN x);
_DecimalNx quantumdNx(_DecimalNx x);
long long int llquantexpdN(_DecimalN x);
long long int llquantexpdNx(_DecimalNx x);
(7.12.16) Decimal re-encoding functions
void encodedecdN(unsigned char * restrict encptr,
const _DecimalN * restrict xptr);
void decodedecdN(_DecimalN * restrict xptr,
const unsigned char * restrict encptr);
void encodebindN(unsigned char * restrict encptr,
const _DecimalN * restrict xptr);
void decodebindN(_DecimalN * restrict xptr,
const unsigned char * restrict encptr);
(F.10.12) Total order functions
int totalorderfN(const _FloatN *x, const _FloatN *y);
int totalorderfNx(const _FloatNx *x, const _FloatNx *y);
int totalorderdN(const _DecimalN *x, const _DecimalN *y);
int totalorderdNx(const _DecimalNx *x, const _DecimalNx *y);
int totalordermagfN(const _FloatN *x, const _FloatN *y);
int totalordermagfNx(const _FloatNx *x, const _FloatNx *y);
int totalordermagdN(const _DecimalN *x, const _DecimalN *y);
int totalordermagdNx(const _DecimalNx *x, const _DecimalNx *y);
(F.10.13) Payload functions
_FloatN getpayloadfN(const _FloatN *x);
_FloatNx getpayloadfNx(const _FloatNx *x);
_DecimalN getpayloaddN(const _DecimalN *x);
_DecimalNx getpayloaddNx(const _DecimalNx *x);
int setpayloadfN(_FloatN *res, _FloatN pl);
int setpayloadfNx(_FloatNx *res, _FloatNx pl);
int setpayloaddN(_DecimalN *res, _DecimalN pl);
int setpayloaddNx(_DecimalNx *res, _DecimalNx pl);
int setpayloadsigfN(_FloatN *res, _FloatN pl);
int setpayloadsigfNx(_FloatNx *res, _FloatNx pl);
int setpayloadsigdN(_DecimalN *res, _DecimalN pl);
int setpayloadsigdNx(_DecimalNx *res, _DecimalNx pl);
2 The specification of the frexp functions (<IP_ADDRESS>) applies to the functions for binary floating types
like those for standard floating types: the exponent is an integral power of 2 and, when applicable,
value equals x × 2*exp .
3 The specification of the ldexp functions (<IP_ADDRESS>) applies to the functions for binary floating types
like those for standard floating types: they return x × 2exp .
4 The specification of the logb functions (<IP_ADDRESS>) applies to binary floating types, with b = 2.
5 The specification of the scalbn and scalbln functions (<IP_ADDRESS>) applies to binary floating types,
with b = 2.
H.11.3 [Encoding conversion functions]
1 This subclause introduces <math.h> functions that, together with the numerical conversion functions
for encodings in H.12, support the non-arithmetic interchange formats specified by IEC 60559.
Support for these formats is an optional feature of this annex. Implementations that do not support
non-arithmetic interchange formats need not declare the functions in this subclause.
2 Non-arithmetic interchange formats are not associated with floating types. Arrays of element
type unsigned char are used as parameters for conversion functions, to represent encodings in
interchange formats that might be non-arithmetic formats.
H.11.3.1 [Encode and decode functions]
1 This subclause specifies functions to map representations in binary floating types to and from
encodings in unsigned char arrays.
H.<IP_ADDRESS> [The encodefN functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <math.h>
void encodefN(unsigned char encptr[restrict static N/8],
const _FloatN * restrict xptr);
Description
2 The encodefN functions convert *xptr into an IEC 60559 binaryN encoding and store the resulting
encoding as an N /8 element array, with 8 bits per array element, in the object pointed to by encptr.
The order of bytes in the array is implementation-defined. These functions preserve the value of
*xptr and raise no floating-point exceptions. If *xptr is non-canonical, these functions may or may
not produce a canonical encoding.
Returns
3 The encodefN functions return no value.
H.<IP_ADDRESS> [The decodefN functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <math.h>
void decodefN(_FloatN * restrict xptr,
const unsigned char encptr[restrict static N/8]);
Description
2 The decodefN functions interpret the N /8 element array pointed to by encptr as an IEC 60559
binaryN encoding, with 8 bits per array element. The order of bytes in the array is implementation-
defined. These functions convert the given encoding into a representation in the type _FloatN, and
store the result in the object pointed to by xptr. These functions preserve the encoded value and
raise no floating-point exceptions. If the encoding is non-canonical, these functions may or may not
produce a canonical representation.
Returns
3 The decodefN functions return no value.
4 See EXAMPLE in H.<IP_ADDRESS>.
H.11.3.2 [Encoding-to-encoding conversion functions]
1 An implementation shall declare an fMencfN function for each M and N equal to the width of
a supported IEC 60559 arithmetic or non-arithmetic binary interchange format, M ̸= N . An
implementation shall provide both dMencdecdN and dMencbindNfunctions for each M and N equal
to the width of a supported IEC 60559 arithmetic or non-arithmetic decimal interchange format,
M ̸= N .
H.<IP_ADDRESS> [The fMencfN functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <math.h>
void fMencfN(unsigned char encMptr[restrict static M/8],
const unsigned char encNptr[restrict static N/8]);
Description
2 The fMencfN functions convert between IEC 60559 binary interchange formats. These functions
interpret the N /8 element array pointed to by encNptr as an encoding of width N bits. They
convert the encoding to an encoding of width M bits and store the resulting encoding as an M /8
element array in the object pointed to by encMptr. The conversion rounds and raises floating-point
exceptions as specified in IEC 60559. The order of bytes in the arrays is implementation-defined.
Returns
3 These functions return no value.
4 EXAMPLE If the IEC 60559 binary16 format is supported as a non-arithmetic format, data in binary16 format can be
converted to type float as follows:
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <math.h>
unsigned char b16[2]; // for input binary16 datum
float f; // for result
unsigned char b32[4];
_Float32 f32;
// store input binary16 datum in array b16
...
f32encf16(b32, b16);
decodef32(&f32, b32);
f = f32;
...
H.<IP_ADDRESS> [The dMencdecdN and dMencbindN functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <math.h>
void dMencdecdN(unsigned char encMptr[restrict static M/8],
const unsigned char encNptr[restrict static N/8]);
void dMencbindN(unsigned char encMptr[restrict static M/8],
const unsigned char encNptr[restrict static N/8]);
Description
2 The dMencdecdN and dMencbindN functions convert between IEC 60559 decimal interchange formats
that use the same encoding scheme. The dMencdecdN functions convert between formats using the
encoding scheme based on decimal encoding of the significand. The dMencbindN functions convert
between formats using the encoding scheme based on binary encoding of the significand. These
functions interpret the N /8 element array pointed to by encNptr as an encoding of width N bits.
They convert the encoding to an encoding of width M bits and store the resulting encoding as an M /8
element array in the object pointed to by encMptr. The conversion rounds and raises floating-point
exceptions as specified in IEC 60559. The order of bytes in the arrays is implementation-defined.
Returns
3 These functions return no value.
H.12 [Numeric conversion functions <stdlib.h>]
1 This clause expands the specification of numeric conversion functions in <stdlib.h> (7.24.1) to also
include conversions of strings from and to interchange and extended floating types. The conversions
from floating are provided by functions analogous to the strfromd function. The conversions to
floating are provided by functions analogous to the strtod function.
2 This clause also specifies functions to convert strings from and to IEC 60559 interchange format
encodings.
3 For each interchange or extended floating type that the implementation provides, <stdlib.h> shall
declare the associated functions specified below in H.12.1 and H.12.2 (see H.8). Conversely, for each
such type that the implementation does not provide, <stdlib.h> shall not declare the associated
functions.
4 For each IEC 60559 arithmetic or non-arithmetic format that the implementation supports,
<stdlib.h> shall declare the associated functions specified below in H.12.3 and H.12.4 (see H.8).
Conversely, for each such format that the implementation does not provide, <stdlib.h> shall not
declare the associated functions.
H.12.1 [String from floating]
1 This subclause expands <IP_ADDRESS> and <IP_ADDRESS> to also include functions for the interchange and
extended floating types. It adds to the synopsis in <IP_ADDRESS> the prototypes
int strfromfN(char * restrict s, size_t n,
const char * restrict format, _FloatN fp);
int strfromfNx(char * restrict s, size_t n,
const char * restrict format, _FloatNx fp);
It encompasses the prototypes in <IP_ADDRESS> by replacing them with
int strfromdN(char * restrict s, size_t n,
const char * restrict format, _DecimalN fp);
int strfromdNx(char * restrict s, size_t n,
const char * restrict format, _DecimalNx fp);
2 The descriptions and returns for the added functions are analogous to the ones in <IP_ADDRESS>
and <IP_ADDRESS>.
H.12.2 [String to floating]
1 This subclause expands <IP_ADDRESS> and <IP_ADDRESS> to also include functions for the interchange and
extended floating types. It adds to the synopsis in <IP_ADDRESS> the prototypes
_FloatN strtofN(const char * restrict nptr,
char ** restrict endptr);
_FloatNx strtofNx(const char * restrict nptr,
char ** restrict endptr);
It encompasses the prototypes in <IP_ADDRESS> by replacing them with
_DecimalN strtodN(const char * restrict nptr,
char ** restrict endptr);
_DecimalNx strtodNx(const char * restrict nptr,
char ** restrict endptr);
2 The descriptions and returns for the added functions are analogous to the ones in <IP_ADDRESS> and <IP_ADDRESS>.
3 For implementations that support both binary and decimal floating types and a (binary or dec-
imal) non-arithmetic interchange format, the strtodN and strtodNx functions (and hence the
strtoencdecdN and strtoencbindN functions in H.12.4.2) shall accept subject sequences that have
the form of hexadecimal floating numbers and otherwise meet the requirements of subject sequences
(<IP_ADDRESS>). Then the decimal results shall be correctly rounded if the subject sequence has at most
M significant hexadecimal digits, where M ≥ ⌈(P − 1)/4⌉ + 1 is implementation-defined, and P is
the maximum precision of the supported binary floating types and binary non-arithmetic formats.
If all subject sequences of hexadecimal form are correctly rounded, M may be regarded as infinite.
If the subject sequence has more than M significant hexadecimal digits, the implementation may
first round to M significant hexadecimal digits according to the applicable rounding direction mode,
signaling exceptions as though converting from a wider format, then correctly round the result of
the shortened hexadecimal input to the result type.
4 EXAMPLE If the IEC 60559 binary128 format is supported as a non-arithmetic format, data in binary128 format can be
converted to type _Decimal128 as follows:
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <stdlib.h>
#define MAXSIZE 41 // > intermediate hex string length
unsigned char b128[16]; // for input binary128 datum
_Decimal128 d128; // for result
char s[MAXSIZE];
// store input binary128 datum in array b128
...
strfromencf128(s, MAXSIZE, "%a", b128);
d128 = strtod128(s, NULL);
...
Use of "%a" for formatting assures an exact conversion of the value in binary format to character sequence. The value of that
character sequence will be correctly rounded to _Decimal128 , as specified above in this subclause. The array s for the output
of strfromencf128 need have no greater size than 41, which is the maximum length of strings of the form
[−]0xh.h . . . hp ± d
where there are up to 29 hexadecimal digits h and d has 5 digits plus 1 for the null character.
H.12.3 [String from encoding]
1 An implementation shall declare the strfromencfN function for each N equal to the width of a
supported IEC 60559 arithmetic or non-arithmetic binary interchange format. An implementation
shall declare both the strfromencdecdN and strfromencbindN functions for each N equal to the
width of a supported IEC 60559 arithmetic or non-arithmetic decimal interchange format.
H.12.3.1 [The strfromencf N functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <stdlib.h>
int strfromencfN(char * restrict s, size_t n, const char * restrict format,
const unsigned char encptr[restrict static N/8]);
Description
2 The strfromencfN functions are similar to the strfromfN functions, except the input is the value of
the N /8 element array pointed to by encptr, interpreted as an IEC 60559 binaryN encoding. The
order of bytes in the arrays is implementation-defined.
Returns
3 The strfromencfN functions return the same values as corresponding strfromfN functions.
H.12.3.2 [The strfromencdecdN and strfromencbindN functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <stdlib.h>
int strfromencdecdN(char * restrict s, size_t n, const char * restrict format,
const unsigned char encptr[restrict static N/8]);
int strfromencbindN(char * restrict s, size_t n, const char * restrict format,
const unsigned char encptr[restrict static N/8]);
Description
2 The strfromencdecdN functions are similar to the strfromdN functions except the input is the value
of the N /8 element array pointed to by encptr, interpreted as an IEC 60559 decimalN encoding in
the coding scheme based on decimal encoding of the significand. The strfromencbindN functions
are similar to the strfromdN functions except the input is the value of the N /8 element array pointed
to by encptr, interpreted as an IEC 60559 decimalN encoding in the coding scheme based on binary
encoding of the significand. The order of bytes in the arrays is implementation-defined.
Returns
3 The strfromencdecdN and strfromencbindN functions return the same values as corresponding
strfromdN functions.
H.12.4 [String to encoding]
1 An implementation shall declare the strtoencfN function for each N equal to the width of a
supported IEC 60559 arithmetic or non-arithmetic binary interchange format. An implementation
shall declare both the strtoencdecdN and strtoencbindN functions for each N equal to the width
of a supported IEC 60559 arithmetic or non-arithmetic decimal interchange format.
H.12.4.1 [The strtoencfN functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <stdlib.h>
void strtoencfN(unsigned char encptr[restrict static N/8],
const char * restrict nptr, char ** restrict endptr);
Description
2 The strtoencfN functions are similar to the strtofN functions, except they store an IEC 60559
encoding of the result as an N /8 element array in the object pointed to by encptr. The order of
bytes in the arrays is implementation-defined.
Returns
3 These functions return no value.
H.12.4.2 [The strtoencdecdN and strtoencbindN functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <stdlib.h>
void strtoencdecdN(unsigned char encptr[restrict static N/8],
const char * restrict nptr, char ** restrict endptr);
void strtoencbindN(unsigned char encptr[restrict static N/8],
const char * restrict nptr, char ** restrict endptr);
Description
2 The strtoencdecdN and strtoencbindNfunctions are similar to the strtodN functions, except
they store an IEC 60559 encoding of the result as an N /8 element array in the object pointed to
by encptr. The strtoencdecdN functions produce an encoding in the encoding scheme based on
decimal encoding of the significand. The strtoencbindN functions produce an encoding in the
encoding scheme based on binary encoding of the significand. The order of bytes in the arrays is
implementation-defined.
Returns
3 These functions return no value.
H.13 [Type-generic macros <tgmath.h>]
1 This clause enhances the specification of type-generic macros in <tgmath.h> (7.27) to apply to
interchange and extended floating types, as well as standard floating types.
2 If arguments for generic parameters of a type-generic macro are such that some argument has
a corresponding real type that is a standard floating type or a binary floating type and another
argument is of decimal floating type, the behavior is undefined.
3 The treatment of arguments of integer type in 7.27 is expanded to cases where another argument
has extended type. Arguments of integer type are regarded as having type:
— _Decimal64x , if any argument has a decimal extended type; otherwise
— _Float32x , if any argument has a binary extended type; otherwise
— _Decimal64 , if any argument has decimal type; otherwise
— double
4 Use of the macros carg, cimag, conj, cproj, or creal with any argument of standard floating type,
binary floating type, complex type, or imaginary type invokes a complex function. Use of the macro
with an argument of a decimal floating type results in undefined behavior.
5 The functions that round results to a narrower type have type-generic macros whose names are
obtained by omitting any suffix from the function names. Thus, the macros with f or d prefix are (as
in 7.27):
fadd fmul ffma
dadd dmul dfma
fsub fdiv fsqrt
dsub ddiv dsqrt
and the macros with fM, fMx, dM, or dMx prefix are:
fMadd fMxmul dMfma
fMsub fMxdiv dMsqrt
fMmul fMxfma dMxadd
fMdiv fMxsqrt dMxsub
fMfma dMadd dMxmul
fMsqrt dMsub dMxdiv
fMxadd dMmul dMxfma
fMxsub dMdiv dMxsqrt
All arguments are generic. If any argument is not real, use of the macro results in undefined behavior.
The following specification uses the notation type1 ⊆ type2 to mean the values of type1 are a subset
of (or the same as) the values of type2. The generic parameter type T for the function invoked by the
macro is determined as follows:
— First, obtain a preliminary type P for the generic parameters: if all arguments are of integer
type, then P is double if the macro prefix is f, d, fN, or fNx and P is _Decimal64 if the macro
prefix is dN or dNx; otherwise (if some argument is not of integer type), apply the rules (for
determining the corresponding real type of the generic parameters) in 7.27 for macros that
do not round result to narrower type, using the usual arithmetic conversion rules in H.4.2, to
obtain P .
— If there exists a corresponding function whose generic parameters have type P , then T is P .
— Otherwise, T is determined from P and the macro prefix as follows:
• For prefix f: if P is a standard or binary floating type, then T is the first standard floating
type of either double or long double, such that P ⊆ T , if such a type T exists. Otherwise
(if no such type T exists or P is a decimal floating type), the behavior is undefined.
• For prefix d: if P is a standard or binary floating type, then T is long double if P ⊆
long double. Otherwise (if P ⊆ long double is false or P is a decimal floating type),
the behavior is undefined.
• For prefix fM: if P is a standard or binary floating type, then T is _FloatN for minimum
N > M such that P ⊆ T , if such a type T is supported; otherwise T is _FloatNx for
minimum N ≥ M such that P ⊆ T , if such a type T is supported. Otherwise (if no
such _FloatN or _FloatNx is supported or P is a decimal floating type), the behavior is
undefined.
• For prefix fMx: if P is a standard or binary floating type, then T is _FloatNx for minimum
N > M such that P ⊆ T , if such a type T is supported; otherwise T is _FloatN for
minimum N > M such that P ⊆ T , if such a type T is supported. Otherwise (if no
such _FloatNx or _FloatN is supported or P is a decimal floating type), the behavior is
undefined.
• For prefix dM: if P is a decimal floating type, then T is _DecimalN for minimum N > M
such that P ⊆ T , if such a type T is supported; otherwise T is _DecimalNx for minimum
N ≥ M such that P ⊆ T . Otherwise (P is a standard or binary floating type), the behavior
is undefined.
• For prefix dMx: if P is a decimal floating type, then T is _DecimalNx for minimum N > M
such that P ⊆ T , if such a type T is supported; otherwise T is _DecimalN for minimum
N > M such that P ⊆ T , if such a type T is supported. Otherwise (P is a standard or
binary floating type), the behavior is undefined.
6 EXAMPLE With the declarations
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <tgmath.h>
int n;
double d;
long double ld;
double complex dc;
_Float32x f32x;
_Float64 f64;
_Float64x f64x;
_Float128 f128;
_Float64x complex f64xc;
functions invoked by use of type-generic macros are shown in the following table, where type1 ⊆ type2 means the values of
type1 are a subset of (or the same as) the values of type2, and type1 ⊂ type2 means the values of type1 are a strict subset of
the values of type2:
macro use invokes
cos(f64xc) ccosf64x
pow(dc, f128) cpowf128
pow(f64, d) powf64
pow(d, f32x) pow, the function, if _Float32x ⊆ double, else powf32x if double ⊂
_Float32x , else undefined
pow(f32, n) pow, the function
pow(f32x, n) pow32x
Macros that round the result to a narrower type. . .
macro use invokes
fsub(d, ld) fsubl
dsub(d, f32) dsubl
undefined
fmul(dc, d)
ddiv(ld, f128) ddivl if _Float128 ⊆ long double, else undefined
f32add(f64x, f64) f32addf64x
f32xsqrt(n) f32xsqrtf64
f32mul(f128, f32x) f32mulf128 if _Float32x ⊆ _Float128 , else f32mulf32x if _Float128
⊂ _Float32x , else undefined
f32fma(f32x, n, f32x) f32fmaf32x
f32add(f32, f32) f32addf64
f32xsqrt(f32) f32xsqrtf64x, as declaration above shows _Float64x is supported
f64div(f32x, f32x) f64divf128 if _Float32x ⊆ _Float128 , else f64divf64x
I. [Annex I (informative) Common warnings]
1 An implementation may generate warnings in many situations, none of which are specified as part
of this document. The following are a few of the more common situations.
2 — A new struct or union type appears in a function prototype (6.2.1, <IP_ADDRESS>).
— A block with initialization of an object that has automatic storage duration is jumped into
(6.2.4).
— An implicit narrowing conversion is encountered, such as the assignment of a long int or a
double to an int, or a pointer to void to a pointer to any type other than a character type (6.3).
— A hexadecimal floating constant cannot be represented exactly in its evaluation format (<IP_ADDRESS>).
— An integer character constant includes more than one character or a wide character constant
includes more than one multibyte character (<IP_ADDRESS>).
— The characters /* are found in a comment (6.4.7).
— An "unordered" binary operator (not comma, &&, or ||) contains a side effect to an lvalue in
one operand, and a side effect to, or an access to the value of, the identical lvalue in the other
operand (6.5).
— An object is defined but not used (6.7).
— A value is given to an object of an enumerated type other than by assignment of an enumeration
constant that is a member of that type, or an enumeration object that has the same type, or the
value of a function that returns the same enumerated type (<IP_ADDRESS>).
— An aggregate has a partly bracketed initialization (6.7.8).
— A statement cannot be reached (6.8).
— A statement with no apparent effect is encountered (6.8).
— A constant expression is used as the controlling expression of a selection statement (6.8.4).
— An incorrectly formed preprocessing group is encountered while skipping a preprocessing
group (6.10.1).
— An unrecognized #pragma directive is encountered (6.10.7).
J. [Annex J (informative) Portability issues]
1 This annex collects some information about portability that appears in this document.
J.1 [Unspecified behavior]
1 The following are unspecified:
— The manner and timing of static initialization (5.1.2).
— The termination status returned to the hosted environment if the return type of main is not
compatible with int (<IP_ADDRESS>.3).
— The values of objects that are neither lock-free atomic objects nor of type
volatile sig_atomic_t and the state of the floating-point environment, when the
processing of the abstract machine is interrupted by receipt of a signal (<IP_ADDRESS>).
— The behavior of the display device if a printing character is written when the active position is
at the final position of a line (5.2.2).
— The behavior of the display device if a backspace character is written when the active position
is at the initial position of a line (5.2.2).
— The behavior of the display device if a horizontal tab character is written when the active
position is at or past the last defined horizontal tabulation position (5.2.2).
— The behavior of the display device if a vertical tab character is written when the active position
is at or past the last defined vertical tabulation position (5.2.2).
— How an extended source character that does not correspond to a universal character name
counts toward the significant initial characters in an external identifier (<IP_ADDRESS>).
— Many aspects of the representations of types (6.2.6).
— The value of padding bytes when storing values in structures or unions (<IP_ADDRESS>).
— The values of bytes that correspond to union members other than the one last stored into
(<IP_ADDRESS>).
— The representation used when storing a value in an object that has more than one object
representation for that value (<IP_ADDRESS>).
— The values of any padding bits in integer representations (<IP_ADDRESS>).
— Whether two string literals result in distinct arrays (6.4.5).
— The order in which subexpressions are evaluated and the order in which side effects take place,
except as specified for the function-call () , &&, ||, ?:, and comma operators (6.5).
— The order in which the function designator, arguments, and subexpressions within the argu-
ments are evaluated in a function call (<IP_ADDRESS>).
— The order of side effects among compound literal initialization list expressions (<IP_ADDRESS>).
— The order in which the operands of an assignment operator are evaluated (6.5.16).
— The alignment of the addressable storage unit allocated to hold a bit-field (<IP_ADDRESS>).
— Whether a call to an inline function uses the inline definition or the external definition of the
function (6.7.4).
— Whether or not a size expression is evaluated when it is part of the operand of a sizeof
operator and changing the value of the size expression would not affect the result of the
operator (<IP_ADDRESS>).
— The order in which any side effects occur among the initialization list expressions in an
initializer (6.7.10).
— The layout of storage for function parameters (6.9.1).
— When a fully expanded macro replacement list contains a function-like macro name as its
last preprocessing token and the next preprocessing token from the source file is a ( , and
the fully expanded replacement of that macro ends with the name of the first macro and the
next preprocessing token from the source file is again a ( , whether that is considered a nested
replacement (6.10.4).
— The order in which # and ## operations are evaluated during macro substitution (<IP_ADDRESS>,
and <IP_ADDRESS>).
— The line number of a preprocessing token, in particular __LINE__ , that spans multiple physical
lines (6.10.5).
— The line number of a preprocessing directive that spans multiple physical lines (6.10.5).
— The line number of a macro invocation that spans multiple physical or logical lines (6.10.5).
— The line number following a directive of the form #line __LINE__ new-line (6.10.5).
— The state of the floating-point status flags when execution passes from a part of the program
translated with FENV_ACCESS "off" to a part translated with FENV_ACCESS "on" (7.6.1).
— The order in which feraiseexcept raises floating-point exceptions, except as stated in F.8.6
(<IP_ADDRESS>).
— Whether math_errhandling is a macro or an identifier with external linkage (7.12).
— The results of the frexp functions when the specified value is not a floating-point number
(<IP_ADDRESS>).
— The numeric result of the ilogb functions when the correct value is outside the range of the
return type (<IP_ADDRESS>, F.10.3.8).
— The result of rounding when the value is out of range (<IP_ADDRESS>, <IP_ADDRESS>, F.10.6.5).
— The value stored by the remquo functions in the object pointed to by quo when y is zero
(<IP_ADDRESS>).
— Whether a comparison macro argument that is represented in a format wider than its semantic
type is converted to the semantic type (7.12.17).
— Whether setjmp is a macro or an identifier with external linkage (7.13).
— Whether va_copy and va_end are macros or identifiers with external linkage (7.16.1).
— The hexadecimal digit before the decimal point when a non-normalized floating-point number
is printed with an a or A conversion specifier (<IP_ADDRESS>, <IP_ADDRESS>).
— The value of the file position indicator after a successful call to the ungetc function for a text
stream, or the ungetwc function for any stream, until all pushed-back characters are read or
discarded (<IP_ADDRESS>, <IP_ADDRESS>).
— The details of the value stored by the fgetpos function (<IP_ADDRESS>).
— The details of the value returned by the ftell function for a text stream (<IP_ADDRESS>).
— Whether the strtod, strtof, strtold, wcstod, wcstof, and wcstold functions convert a
minus-signed sequence to a negative number directly or by negating the value resulting from
converting the corresponding unsigned sequence (<IP_ADDRESS>, <IP_ADDRESS>.2).
— The order and contiguity of storage allocated by successive calls to the calloc, malloc,
realloc, and aligned_alloc functions (7.24.3).
— The amount of storage allocated by a successful call to the calloc, malloc, realloc, or
aligned_alloc function when 0 bytes was requested (7.24.3).
— Whether a call to the atexit function that does not happen before the exit function is called
will succeed (<IP_ADDRESS>).
— Whether a call to the at_quick_exit function that does not happen before the quick_exit
function is called will succeed (<IP_ADDRESS>).
— Which of two elements that compare as equal is matched by the bsearch function (<IP_ADDRESS>).
— The order of two elements that compare as equal in an array sorted by the qsort function
(<IP_ADDRESS>).
— The order in which destructors are invoked by thrd_exit (<IP_ADDRESS>).
— Whether calling tss_delete on a key while another thread is executing destructors affects the
number of invocations of the destructors associated with the key on that thread (<IP_ADDRESS>).
— The encoding of the calendar time returned by the time function (<IP_ADDRESS>).
— The characters stored by the strftime or wcsftime function if any of the time values being
converted is outside the normal range (<IP_ADDRESS>, <IP_ADDRESS>).
— Whether an encoding error occurs if a wchar_t value that does not correspond to a member of
the extended character set appears in the format string for a function in 7.31.2 or 7.31.5 and the
specified semantics do not require that value to be processed by wcrtomb (7.31.1).
— The conversion state after an encoding error occurs (<IP_ADDRESS>.2, <IP_ADDRESS>.3, <IP_ADDRESS>.1, <IP_ADDRESS>.2,
and <IP_ADDRESS>, <IP_ADDRESS>, <IP_ADDRESS>, <IP_ADDRESS>, <IP_ADDRESS>, <IP_ADDRESS>).
— The resulting value when the "invalid" floating-point exception is raised during IEC 60559
floating to integer conversion (F.4).
— Whether conversion of non-integer IEC 60559 floating values to integer raises the "inexact"
floating-point exception (F.4).
— Whether or when library functions in <math.h> raise the "inexact" floating-point exception in
an IEC 60559 conformant implementation (F.10).
— Whether or when library functions in <math.h> raise an undeserved "underflow" floating-
point exception in an IEC 60559 conformant implementation (F.10).
— The exponent value stored by frexp for a NaN or infinity (F.10.3.7).
— The numeric result returned by the lrint, llrint, lround, and llround functions if the
rounded value is outside the range of the return type (F.10.6.5, F.10.6.7).
— The sign of one part of the complex result of several math functions for certain special cases
in IEC 60559 compatible implementations (G.6.1.1, G.6.2.2, G.6.2.3, G.6.2.4, G.6.2.5, G.6.2.6,
and G.6.3.1, G.6.4.2).
J.2 [Undefined behavior]
1 The behavior is undefined in the following circumstances:
— A "shall" or "shall not" requirement that appears outside of a constraint is violated (Clause 4).
— A nonempty source file does not end in a new-line character which is not immediately preceded
by a backslash character or ends in a partial preprocessing token or comment (<IP_ADDRESS>).
— Token concatenation produces a character sequence matching the syntax of a universal charac-
ter name (<IP_ADDRESS>).
— A program in a hosted environment does not define a function named main using one of the
specified forms (<IP_ADDRESS>.1).
— The execution of a program contains a data race (<IP_ADDRESS>).
— A character not in the basic source character set is encountered in a source file, except in an
identifier, a character constant, a string literal, a header name, a comment, or a preprocessing
token that is never converted to a token (5.2.1).
— An identifier, comment, string literal, character constant, or header name contains an invalid
multibyte character or does not begin and end in the initial shift state (<IP_ADDRESS>).
— The same identifier has both internal and external linkage in the same translation unit (6.2.2).
— An object is referred to outside of its lifetime (6.2.4).
— The value of a pointer to an object whose lifetime has ended is used (6.2.4).
— The value of an object with automatic storage duration is used while the object has an indeter-
minate representation (6.2.4, 6.7.10, 6.8).
— A non-value representation is read by an lvalue expression that does not have character type
(<IP_ADDRESS>).
— A non-value representation is produced by a side effect that modifies any part of the object
using an lvalue expression that does not have character type (<IP_ADDRESS>).
— Two declarations of the same object or function specify types that are not compatible (6.2.7).
— A program requires the formation of a composite type from a variable length array type whose
size is specified by an expression that is not evaluated (6.2.7).
— Conversion to or from an integer type produces a value outside the range that can be repre-
sented (<IP_ADDRESS>).
— Demotion of one real floating type to another produces a value outside the range that can be
represented (<IP_ADDRESS>).
— An lvalue does not designate an object when evaluated (<IP_ADDRESS>).
— A non-array lvalue with an incomplete type is used in a context that requires the value of the
designated object (<IP_ADDRESS>).
— An lvalue designating an object of automatic storage duration that could have been declared
with the register storage class is used in a context that requires the value of the designated
object, but the object is uninitialized. (<IP_ADDRESS>).
— An lvalue having array type is converted to a pointer to the initial element of the array, and
the array object has register storage class (<IP_ADDRESS>).
— An attempt is made to use the value of a void expression, or an implicit or explicit conversion
(except to void) is applied to a void expression (<IP_ADDRESS>).
— Conversion of a pointer to an integer type produces a value outside the range that can be
represented (<IP_ADDRESS>).
— Conversion between two pointer types produces a result that is incorrectly aligned (<IP_ADDRESS>).
— A pointer is used to call a function whose type is not compatible with the referenced type
(<IP_ADDRESS>).
— An unmatched ’ or " character is encountered on a logical source line during tokenization
(6.4).
— A reserved keyword token is used in translation phase 7 or 8 for some purpose other than as a
keyword (6.4.1).
— A universal character name in an identifier does not designate a character whose encoding
falls into one of the specified ranges (<IP_ADDRESS>).
— The initial character of an identifier is a universal character name designating a digit (<IP_ADDRESS>).
— Two identifiers differ only in nonsignificant characters (<IP_ADDRESS>).
— The identifier __func__ is explicitly declared (<IP_ADDRESS>).
— The program attempts to modify a string literal (6.4.5).
— The characters ’ , \ , ", // , or /* occur in the sequence between the < and > delimiters, or the
characters ’ , \ , // , or /* occur in the sequence between the " delimiters, in a header name
preprocessing token (6.4.7).
— A side effect on a scalar object is unsequenced relative to either a different side effect on the
same scalar object or a value computation using the value of the same scalar object (6.5).
— An exceptional condition occurs during the evaluation of an expression (6.5).
— An object has its stored value accessed other than by an lvalue of an allowable type (6.5).
— A function is defined with a type that is not compatible with the type (of the expression)
pointed to by the expression that denotes the called function (<IP_ADDRESS>).
— A member of an atomic structure or union is accessed (<IP_ADDRESS>).
— The operand of the unary * operator has an invalid value (<IP_ADDRESS>).
— A pointer is converted to other than an integer or pointer type (6.5.4).
— The value of the second operand of the / or % operator is zero (6.5.5).
— If the quotient a/b is not representable, the behavior of both a/b and a%b (6.5.5).
— Addition or subtraction of a pointer into, or just beyond, an array object and an integer type
produces a result that does not point into, or just beyond, the same array object (6.5.6).
— Addition or subtraction of a pointer into, or just beyond, an array object and an integer type
produces a result that points just beyond the array object and is used as the operand of a unary
* operator that is evaluated (6.5.6).
— Pointers that do not point into, or just beyond, the same array object are subtracted (6.5.6).
— An array subscript is out of range, even if an object is apparently accessible with the given
subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).
— The result of subtracting two pointers is not representable in an object of type ptrdiff_t
(6.5.6).
— An expression is shifted by a negative number or by an amount greater than or equal to the
width of the promoted expression (6.5.7).
— An expression having signed promoted type is left-shifted and either the value of the expres-
sion is negative or the result of shifting would not be representable in the promoted type
(6.5.7).
— Pointers that do not point to the same aggregate or union (nor just beyond the same array
object) are compared using relational operators (6.5.8).
— An object is assigned to an inexactly overlapping object or to an exactly overlapping object
with incompatible type (<IP_ADDRESS>).
— An expression that is required to be an integer constant expression does not have an integer
type; has operands that are not integer constants, enumeration constants, character constants,
predefined constants, sizeof expressions whose results are integer constants, alignof expres-
sions, or immediately-cast floating constants; or contains casts (outside operands to sizeof
and alignof operators) other than conversions of arithmetic types to integer types (6.6).
— A constant expression in an initializer is not, or does not evaluate to, one of the following: an
arithmetic constant expression, a null pointer constant, an address constant, or an address
constant for a complete object type plus or minus an integer constant expression (6.6).
— An arithmetic constant expression does not have arithmetic type; has operands that are not
integer constants, floating constants, enumeration constants, character constants, predefined
constants, sizeof expressions whose results are integer constants, or alignof expressions; or
contains casts (outside operands to sizeof or alignof operators) other than conversions of
arithmetic types to arithmetic types (6.6).
— The value of an object is accessed by an array-subscript [], member-access . or-> , address &,
or indirection * operator or a pointer cast in creating an address constant (6.6).
— An identifier for an object is declared with no linkage and the type of the object is incomplete
after its declarator, or after its init-declarator if it has an initializer (6.7).
— A function is declared at block scope with an explicit storage-class specifier other than extern
(6.7.1).
— A structure or union is defined without any named members (including those specified
indirectly via anonymous structures and unions) (<IP_ADDRESS>).
— An attempt is made to access, or generate a pointer to just past, a flexible array member of a
structure when the referenced object provides no elements for that array (<IP_ADDRESS>).
— When the complete type is needed, an incomplete structure or union type is not completed in
the same scope by another declaration of the tag that defines the content (<IP_ADDRESS>).
— An attempt is made to modify an object defined with a const-qualified type through use of an
lvalue with non-const-qualified type (6.7.3).
— An attempt is made to refer to an object defined with a volatile-qualified type through use of
an lvalue with non-volatile-qualified type (6.7.3).
— The specification of a function type includes any type qualifiers (6.7.3).
— Two qualified types that are required to be compatible do not have the identically qualified
version of a compatible type (6.7.3).
— An object which has been modified is accessed through a restrict-qualified pointer to a const-
qualified type, or through a restrict-qualified pointer and another pointer that are not both
based on the same object (<IP_ADDRESS>).
— A restrict-qualified pointer is assigned a value based on another restricted pointer whose
associated block neither began execution before the block associated with this pointer, nor
ended before the assignment (<IP_ADDRESS>).
— A function with external linkage is declared with an inline function specifier, but is not also
defined in the same translation unit (6.7.4).
— A function declared with a _Noreturn function specifier returns to its caller (6.7.4).
— The definition of an object has an alignment specifier and another declaration of that object
has a different alignment specifier (6.7.5).
— Declarations of an object in different translation units have different alignment specifiers
(6.7.5).
— Two pointer types that are required to be compatible are not identically qualified, or are not
pointers to compatible types (<IP_ADDRESS>).
— The size expression in an array declaration is not a constant expression and evaluates at
program execution time to a nonpositive value (<IP_ADDRESS>).
— In a context requiring two array types to be compatible, they do not have compatible element
types, or their size specifiers evaluate to unequal values (<IP_ADDRESS>).
— A declaration of an array parameter includes the keyword static within the [ and ] and the
corresponding argument does not provide access to the first element of an array with at least
the specified number of elements (<IP_ADDRESS>).
— A storage-class specifier or type qualifier modifies the keyword void as a function parameter
type list (<IP_ADDRESS>).
— In a context requiring two function types to be compatible, they do not have compatible return
types, or their parameters disagree in use of the ellipsis terminator or the number and type of
parameters (after default argument promotion, when there is no parameter type list) (<IP_ADDRESS>).
— A declaration for which a type is inferred contains a pointer, array, or function declarators
(6.7.9).
— A declaration for which a type is inferred contains no or more than one declarators (6.7.9).
— The value of an unnamed member of a structure or union is used (6.7.10).
— The initializer for a scalar is neither a single expression nor a single expression enclosed in
braces (6.7.10).
— The initializer for a structure or union object that has automatic storage duration is neither an
initializer list nor a single expression that has compatible structure or union type (6.7.10).
— The initializer for an aggregate or union, other than an array initialized by a string literal, is
not a brace-enclosed list of initializers for its elements or members (6.7.10).
— A function definition that does not have the asserted property is called by a function decla-
ration or a function pointer with a type that has the unsequenced or reproducible attribute
(<IP_ADDRESS>).
— An identifier with external linkage is used, but in the program there does not exist exactly
one external definition for the identifier, or the identifier is not used and there exist multiple
external definitions for the identifier (6.9).
— A function that accepts a variable number of arguments is defined without a parameter type
list that ends with the ellipsis notation (6.9.1).
— The } that terminates a function is reached, and the value of the function call is used by the
caller (6.9.1).
— An identifier for an object with internal linkage and an incomplete type is declared with a
tentative definition (6.9.2).
— A non-directive preprocessing directive is executed (6.10).
— The token defined is generated during the expansion of a #if or #elif preprocessing direc-
tive, or the use of the defined unary operator does not match one of the two specified forms
prior to macro replacement (6.10.1).
— The #include preprocessing directive that results after expansion does not match one of the
two header name forms (6.10.2).
— The character sequence in an #include preprocessing directive does not start with a letter
(6.10.2).
— There are sequences of preprocessing tokens within the list of macro arguments that would
otherwise act as preprocessing directives (6.10.4).
— The result of the preprocessing operator # is not a valid character string literal (<IP_ADDRESS>).
— The result of the preprocessing operator ## is not a valid preprocessing token (<IP_ADDRESS>).
— The #line preprocessing directive that results after expansion does not match one of the two
well-defined forms, or its digit sequence specifies zero or a number greater than<PHONE_NUMBER>
(6.10.5).
— A non-STDC #pragma preprocessing directive that is documented as causing translation failure
or some other form of undefined behavior is encountered (6.10.7).
— A #pragma STDC preprocessing directive does not match one of the well-defined forms (6.10.7).