binary-prefix binary-digit
binary-constant ’opt binary-digit
(<IP_ADDRESS>) hexadecimal-prefix: one of
0x 0X
(<IP_ADDRESS>) binary-prefix: one of
0b 0B
(<IP_ADDRESS>) nonzero-digit: one of
1 2 3 4 5 6 7 8 9
(<IP_ADDRESS>) octal-digit: one of
0 1 2 3 4 5 6 7
hexadecimal-digit-sequence:
hexadecimal-digit
hexadecimal-digit-sequence ’opt hexadecimal-digit
(<IP_ADDRESS>) hexadecimal-digit: one of
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
(<IP_ADDRESS>) binary-digit: one of
0 1
(<IP_ADDRESS>) integer-suffix:
unsigned-suffix long-suffixopt
unsigned-suffix long-long-suffix
unsigned-suffix bit-precise-int-suffix
long-suffix unsigned-suffixopt
long-long-suffix unsigned-suffixopt
bit-precise-int-suffix unsigned-suffixopt
(<IP_ADDRESS>) bit-precise-int-suffix: one of
wb WB
(<IP_ADDRESS>) unsigned-suffix: one of
u U
(<IP_ADDRESS>) long-suffix: one of
l L
(<IP_ADDRESS>) long-long-suffix: one of
ll LL
(<IP_ADDRESS>) floating-constant:
decimal-floating-constant
hexadecimal-floating-constant
(<IP_ADDRESS>) decimal-floating-constant:
fractional-constant exponent-partopt floating-suffixopt
digit-sequence exponent-part floating-suffixopt
(<IP_ADDRESS>) hexadecimal-floating-constant:
hexadecimal-prefix hexadecimal-fractional-constant
binary-exponent-part floating-suffixopt
hexadecimal-prefix hexadecimal-digit-sequence
binary-exponent-part floating-suffixopt
(<IP_ADDRESS>) fractional-constant:
digit-sequenceopt . digit-sequence
digit-sequence .
(<IP_ADDRESS>) exponent-part:
e signopt digit-sequence
E signopt digit-sequence
(<IP_ADDRESS>) sign: one of
+ -
(<IP_ADDRESS>) digit-sequence:
digit
digit-sequence ’opt digit
(<IP_ADDRESS>) hexadecimal-fractional-constant:
hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence
hexadecimal-digit-sequence .
(<IP_ADDRESS>) binary-exponent-part:
p signopt digit-sequence
P signopt digit-sequence
(<IP_ADDRESS>) floating-suffix: one of
f l F L df dd dl DF DD DL
(<IP_ADDRESS>) enumeration-constant:
identifier
(<IP_ADDRESS>) character-constant:
encoding-prefixopt ’ c-char-sequence ’
(<IP_ADDRESS>) encoding-prefix:
u8
u
U
L
(<IP_ADDRESS>) c-char-sequence:
c-char
c-char-sequence c-char
(<IP_ADDRESS>) c-char:
any member of the source character set except
the single-quote ’, backslash \ , or new-line character
escape-sequence
(<IP_ADDRESS>) escape-sequence:
simple-escape-sequence
octal-escape-sequence
hexadecimal-escape-sequence
universal-character-name
(<IP_ADDRESS>) simple-escape-sequence: one of
\’ \" \? \\
\a \b \f \n \r \t \v
(<IP_ADDRESS>) octal-escape-sequence:
\ octal-digit
\ octal-digit octal-digit
\ octal-digit octal-digit octal-digit
(<IP_ADDRESS>) hexadecimal-escape-sequence:
\x hexadecimal-digit
hexadecimal-escape-sequence hexadecimal-digit
(<IP_ADDRESS>) predefined-constant:
false
true
nullptr
A.1.6 [String literals]
(6.4.5) string-literal:
encoding-prefixopt " s-char-sequenceopt "
(6.4.5) s-char-sequence:
s-char
s-char-sequence s-char
(6.4.5) s-char:
any member of the source character set except
the double-quote ", backslash \, or new-line character
escape-sequence
A.1.7 [Punctuators]
(6.4.6) punctuator: one of
[ ] ( ) { } . ->
++ -- & * + - ~ !
/ % << >> < > <= >= == != ^ | && ||
? : :: ; ...
= *= /= %= += -= <<= >>= &= ^= |=
, # ##
<: :> <% %> %: %:%:
A.1.8 [Header names]
(6.4.7) header-name:
< h-char-sequence >
" q-char-sequence "
(6.4.7) h-char-sequence:
h-char
h-char-sequence h-char
(6.4.7) h-char:
any member of the source character set except
the new-line character and >
(6.4.7) q-char-sequence:
q-char
q-char-sequence q-char
(6.4.7) q-char:
any member of the source character set except
the new-line character and "
A.1.9 [Preprocessing numbers]
(6.4.8) pp-number:
digit
. digit
pp-number identifier-continue
pp-number ’ digit
pp-number ’ nondigit
pp-number e sign
pp-number E sign
pp-number p sign
pp-number P sign
pp-number .
(6.5.1) primary-expression:
A.2 [Phrase structure grammar]
A.2.1 [Expressions]
identifier
constant
string-literal
( expression )
generic-selection
(<IP_ADDRESS>) generic-selection:
_Generic ( assignment-expression , generic-assoc-list )
(<IP_ADDRESS>) generic-assoc-list:
generic-association
generic-assoc-list , generic-association
(<IP_ADDRESS>) generic-association:
type-name : assignment-expression
default : assignment-expression
(6.5.2) postfix-expression:
primary-expression
postfix-expression [ expression ]
postfix-expression ( argument-expression-listopt )
postfix-expression . identifier
postfix-expression -> identifier
postfix-expression ++
postfix-expression --
compound-literal
(6.5.2) argument-expression-list:
assignment-expression
argument-expression-list , assignment-expression
(<IP_ADDRESS>) compound-literal:
( storage-class-specifiersopt type-name ) braced-initializer
(<IP_ADDRESS>) storage-class-specifiers:
storage-class-specifier
storage-class-specifiers storage-class-specifier
(6.5.3) unary-expression:
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )
alignof ( type-name )
(6.5.3) unary-operator: one of
& * + - ~ !
(6.5.4) cast-expression:
unary-expression
( type-name ) cast-expression
(6.5.5) multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
(6.5.6) additive-expression:
multiplicative-expression
additive-expression + multiplicative-expression
additive-expression - multiplicative-expression
(6.5.7) shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
(6.5.8) relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
(6.5.9) equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
(6.5.10) AND-expression:
equality-expression
AND-expression & equality-expression
(6.5.11) exclusive-OR-expression:
AND-expression
exclusive-OR-expression ^ AND-expression
(6.5.12) inclusive-OR-expression:
exclusive-OR-expression
inclusive-OR-expression | exclusive-OR-expression
(6.5.13) logical-AND-expression:
inclusive-OR-expression
logical-AND-expression && inclusive-OR-expression
(6.5.14) logical-OR-expression:
logical-AND-expression
logical-OR-expression || logical-AND-expression
(6.5.15) conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
(6.5.16) assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
(6.5.16) assignment-operator: one of
= *= /= %= += -= <<= >>= &= ^= |=
(6.5.17) expression:
assignment-expression
expression , assignment-expression
(6.6) constant-expression:
conditional-expression
(6.7) declaration:
A.2.2 [declaration-specifiers init-declarator-listopt ;]
Declarations
attribute-specifier-sequence declaration-specifiers init-declarator-list ;
static_assert-declaration
attribute-declaration
(6.7) declaration-specifiers:
declaration-specifier attribute-specifier-sequenceopt
declaration-specifier declaration-specifiers
(6.7) declaration-specifier:
storage-class-specifier
type-specifier-qualifier
function-specifier
(6.7) init-declarator-list:
init-declarator
init-declarator-list , init-declarator
(6.7) init-declarator:
declarator
declarator = initializer
(6.7) attribute-declaration:
attribute-specifier-sequence ;
(6.7.1) storage-class-specifier:
auto
constexpr
extern
register
static
thread_local
typedef
(6.7.2) type-specifier:
void
char
short
int
long
float
double
signed
unsigned
_BitInt ( constant-expression )
bool
_Complex
_Decimal32
_Decimal64
_Decimal128
atomic-type-specifier
struct-or-union-specifier
enum-specifier
typedef-name
typeof-specifier
(<IP_ADDRESS>) struct-or-union-specifier:
struct-or-union attribute-specifier-sequenceopt identifieropt { member-declaration-list }
struct-or-union attribute-specifier-sequenceopt identifier
(<IP_ADDRESS>) struct-or-union:
struct
union
(<IP_ADDRESS>) member-declaration-list:
member-declaration
member-declaration-list member-declaration
(<IP_ADDRESS>) member-declaration:
attribute-specifier-sequenceopt specifier-qualifier-list member-declarator-listopt ;
static_assert-declaration
(<IP_ADDRESS>) specifier-qualifier-list:
type-specifier-qualifier attribute-specifier-sequenceopt
type-specifier-qualifier specifier-qualifier-list
(<IP_ADDRESS>) type-specifier-qualifier:
type-specifier
type-qualifier
alignment-specifier
(<IP_ADDRESS>) member-declarator-list:
member-declarator
member-declarator-list , member-declarator
(<IP_ADDRESS>) member-declarator:
declarator
declaratoropt : constant-expression
(<IP_ADDRESS>) enum-specifier:
enum attribute-specifier-sequenceopt identifieropt enum-type-specifieropt
{ enumerator-list }
enum attribute-specifier-sequenceopt identifieropt enum-type-specifieropt
{ enumerator-list , }
enum identifier enum-type-specifieropt
(<IP_ADDRESS>) enumerator-list:
enumerator
enumerator-list , enumerator
(<IP_ADDRESS>) enumerator:
enumeration-constant attribute-specifier-sequenceopt
enumeration-constant attribute-specifier-sequenceopt = constant-expression
(<IP_ADDRESS>) enum-type-specifier:
: specifier-qualifier-list
(<IP_ADDRESS>) atomic-type-specifier:
_Atomic ( type-name )
(<IP_ADDRESS>) typeof-specifier:
typeof ( typeof-specifier-argument )
typeof_unqual ( typeof-specifier-argument )
(<IP_ADDRESS>) typeof-specifier-argument:
expression
type-name
(6.7.3) type-qualifier:
const
restrict
volatile
_Atomic
(6.7.4) function-specifier:
inline
_Noreturn
(6.7.5) alignment-specifier:
alignas ( type-name )
alignas ( constant-expression )
(6.7.6) declarator:
pointeropt direct-declarator
(6.7.6) direct-declarator:
identifier attribute-specifier-sequenceopt
( declarator )
array-declarator attribute-specifier-sequenceopt
function-declarator attribute-specifier-sequenceopt
(6.7.6) array-declarator:
direct-declarator [ type-qualifier-listopt assignment-expressionopt ]
direct-declarator [ static type-qualifier-listopt assignment-expression ]
direct-declarator [ type-qualifier-list static assignment-expression ]
direct-declarator [ type-qualifier-listopt * ]
(6.7.6) function-declarator:
direct-declarator ( parameter-type-listopt )
(6.7.6) pointer:
* attribute-specifier-sequenceopt type-qualifier-listopt
* attribute-specifier-sequenceopt type-qualifier-listopt pointer
(6.7.6) type-qualifier-list:
type-qualifier
type-qualifier-list type-qualifier
(6.7.6) parameter-type-list:
parameter-list
parameter-list , ...
...
(6.7.6) parameter-list:
parameter-declaration
parameter-list , parameter-declaration
(6.7.6) parameter-declaration:
attribute-specifier-sequenceopt declaration-specifiers declarator
attribute-specifier-sequenceopt declaration-specifiers abstract-declaratoropt
(6.7.7) type-name:
specifier-qualifier-list abstract-declaratoropt
(6.7.7) abstract-declarator:
pointer
pointeropt direct-abstract-declarator
(6.7.7) direct-abstract-declarator:
( abstract-declarator )
array-abstract-declarator attribute-specifier-sequenceopt
function-abstract-declarator attribute-specifier-sequenceopt
(6.7.7) array-abstract-declarator:
direct-abstract-declaratoropt [ type-qualifier-listopt assignment-expressionopt ]
direct-abstract-declaratoropt [ static type-qualifier-listopt assignment-expression ]
direct-abstract-declaratoropt [ type-qualifier-list static assignment-expression ]
direct-abstract-declaratoropt [ * ]
(6.7.7) function-abstract-declarator:
direct-abstract-declaratoropt ( parameter-type-listopt )
(6.7.8) typedef-name:
identifier
(6.7.10) braced-initializer:
{ }
{ initializer-list }
{ initializer-list , }
(6.7.10) initializer:
assignment-expression
braced-initializer
(6.7.10) initializer-list:
designationopt initializer
initializer-list , designationopt initializer
(6.7.10) designation:
designator-list =
(6.7.10) designator-list:
designator
designator-list designator
(6.7.10) designator:
[ constant-expression ]
. identifier
(6.7.11) static_assert-declaration:
static_assert ( constant-expression , string-literal ) ;
static_assert ( constant-expression ) ;
(<IP_ADDRESS>) attribute-specifier-sequence:
attribute-specifier-sequenceopt attribute-specifier
(<IP_ADDRESS>) attribute-specifier:
[ [ attribute-list ] ]
(<IP_ADDRESS>) attribute-list:
attributeopt
attribute-list , attributeopt
(<IP_ADDRESS>) attribute:
attribute-token attribute-argument-clauseopt
(<IP_ADDRESS>) attribute-token:
standard-attribute
attribute-prefixed-token
(<IP_ADDRESS>) standard-attribute:
identifier
(<IP_ADDRESS>) attribute-prefixed-token:
attribute-prefix :: identifier
(<IP_ADDRESS>) attribute-prefix:
identifier
(<IP_ADDRESS>) attribute-argument-clause:
( balanced-token-sequenceopt )
(<IP_ADDRESS>) balanced-token-sequence:
balanced-token
balanced-token-sequence balanced-token
(<IP_ADDRESS>) balanced-token:
( balanced-token-sequenceopt )
[ balanced-token-sequenceopt ]
{ balanced-token-sequenceopt }
any token other than a parenthesis, a bracket, or a brace
A.2.3 [Statements]
(6.8) statement:
labeled-statement
unlabeled-statement
(6.8) unlabeled-statement:
expression-statement
attribute-specifier-sequenceopt primary-block
attribute-specifier-sequenceopt jump-statement
(6.8) primary-block:
compound-statement
selection-statement
iteration-statement
(6.8) secondary-block:
statement
(6.8.1) label:
attribute-specifier-sequenceopt identifier :
attribute-specifier-sequenceopt case constant-expression :
attribute-specifier-sequenceopt default :
(6.8.1) labeled-statement:
label statement
(6.8.2) compound-statement:
{ block-item-listopt }
(6.8.2) block-item-list:
block-item
block-item-list block-item
(6.8.2) block-item:
declaration
unlabeled-statement
label
(6.8.3) expression-statement:
expressionopt ;
attribute-specifier-sequence expression ;
(6.8.4) selection-statement:
if ( expression ) secondary-block
if ( expression ) secondary-block else secondary-block
switch ( expression ) secondary-block
(6.8.5) iteration-statement:
while ( expression ) secondary-block
do secondary-block while ( expression ) ;
for ( expressionopt ; expressionopt ; expressionopt ) secondary-block
for ( declaration expressionopt ; expressionopt ) secondary-block
(6.8.6) jump-statement:
goto identifier ;
continue ;
break ;
return expressionopt ;
A.2.4 [External definitions]
(6.9) translation-unit:
external-declaration
translation-unit external-declaration
(6.9) external-declaration:
function-definition
declaration
(6.9.1) function-definition:
attribute-specifier-sequenceopt declaration-specifiers declarator function-body
(6.9.1) function-body:
compound-statement
A.3 [Preprocessing directives]
(6.10) preprocessing-file:
groupopt
(6.10) group:
group-part
group group-part
(6.10) group-part:
if-section
control-line
text-line
# non-directive
(6.10) if-section:
if-group elif-groupsopt else-groupopt endif-line
(6.10) if-group:
# if constant-expression new-line groupopt
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
(6.10) elif-groups:
elif-group
elif-groups elif-group
(6.10) elif-group:
# elif constant-expression new-line groupopt
# elifdef identifier new-line groupopt
# elifndef identifier new-line groupopt
(6.10) else-group:
# else new-line groupopt
(6.10) endif-line:
# endif new-line
(6.10) control-line:
# include pp-tokens new-line
# embed pp-tokens new-line
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
# undef identifier new-line
# line pp-tokens new-line
# error pp-tokensopt new-line
# warning pp-tokensopt new-line
# pragma pp-tokensopt new-line
# new-line
(6.10) text-line:
pp-tokensopt new-line
(6.10) non-directive:
pp-tokens new-line
(6.10) lparen:
a ( character not immediately preceded by white space
(6.10) replacement-list:
pp-tokensopt
(6.10) pp-tokens:
preprocessing-token
pp-tokens preprocessing-token
(6.10) new-line:
the new-line character
(6.10) identifier-list:
identifier
identifier-list , identifier
(6.10) pp-parameter:
pp-parameter-name pp-parameter-clauseopt
(6.10) pp-parameter-name:
pp-standard-parameter
pp-prefixed-parameter
(6.10) pp-standard-parameter:
identifier
(6.10) pp-prefixed-parameter:
identifier :: identifier
(6.10) pp-parameter-clause:
( pp-balanced-token-sequenceopt )
(6.10) pp-balanced-token-sequence:
pp-balanced-token
pp-balanced-token-sequence pp-balanced-token
(6.10) pp-balanced-token:
( pp-balanced-token-sequenceopt )
[ pp-balanced-token-sequenceopt ]
{ pp-balanced-token-sequenceopt }
any pp-token other than a parenthesis, a bracket, or a brace
(6.10) embed-parameter-sequence:
pp-parameter
embed-parameter-sequence pp-parameter
defined-macro-expression:
defined identifier
defined ( identifier )
h-preprocessing-token:
any preprocessing-token other than >
h-pp-tokens:
h-preprocessing-token
h-pp-tokens h-preprocessing-token
header-name-tokens:
string-literal
< h-pp-tokens >
has-include-expression:
__has_include ( header-name )
__has_include ( header-name-tokens )
has-embed-expression:
__has_embed ( header-name embed-parameter-sequenceopt )
__has_embed ( header-name-tokens pp-balanced-token-sequenceopt )
has-c-attribute-express:
__has_c_attribute ( pp-tokens )
va-opt-replacement:
__VA_OPT__ ( pp-tokensopt )
(6.10.7) standard-pragma:
# pragma STDC FP_CONTRACT on-off-switch
# pragma STDC FENV_ACCESS on-off-switch
# pragma STDC FENV_DEC_ROUND dec-direction
# pragma STDC FENV_ROUND direction
# pragma STDC CX_LIMITED_RANGE on-off-switch
(6.10.7) on-off-switch: one of
ON OFF DEFAULT
(6.10.7) direction: one of
FE_DOWNWARD FE_TONEAREST FE_TONEARESTFROMZERO
FE_TOWARDZERO FE_UPWARD FE_DYNAMIC
(6.10.7) dec-direction: one of
FE_DEC_DOWNWARD FE_DEC_TONEAREST FE_DEC_TONEARESTFROMZERO
FE_DEC_TOWARDZERO FE_DEC_UPWARD FE_DEC_DYNAMIC
A.4 [Floating-point subject sequence]
A.4.1 [NaN char sequence]
(<IP_ADDRESS>) n-char-sequence:
digit
nondigit
n-char-sequence digit
n-char-sequence nondigit
A.4.2 [NaN wchar_t sequence]
(<IP_ADDRESS>.2) n-wchar-sequence:
digit
nondigit
n-wchar-sequence digit
n-wchar-sequence nondigit
A.5 [Decimal floating-point subject sequence]
A.5.1 [NaN decimal char sequence]
(<IP_ADDRESS>) d-char-sequence:
digit
nondigit
d-char-sequence digit
d-char-sequence nondigit
A.5.2 [NaN decimal wchar_t sequence]
(<IP_ADDRESS>.3) d-wchar-sequence:
digit
nondigit
d-wchar-sequence digit
d-wchar-sequence nondigit
B. [Annex B (informative) Library summary]
B.1 [Diagnostics <assert.h>]
NDEBUG
void assert(scalar expression);
B.2 [Complex <complex.h>]
__STDC_NO_COMPLEX__ imaginary
complex _Imaginary_I
_Complex_I I
#pragma STDC CX_LIMITED_RANGE on-off-switch
double complex cacos(double complex z);
float complex cacosf(float complex z);
long double complex cacosl(long double complex z);
double complex casin(double complex z);
float complex casinf(float complex z);
long double complex casinl(long double complex z);
double complex catan(double complex z);
float complex catanf(float complex z);
long double complex catanl(long double complex z);
double complex ccos(double complex z);
float complex ccosf(float complex z);
long double complex ccosl(long double complex z);
double complex csin(double complex z);
float complex csinf(float complex z);
long double complex csinl(long double complex z);
double complex ctan(double complex z);
float complex ctanf(float complex z);
long double complex ctanl(long double complex z);
double complex cacosh(double complex z);
float complex cacoshf(float complex z);
long double complex cacoshl(long double complex z);
double complex casinh(double complex z);
float complex casinhf(float complex z);
long double complex casinhl(long double complex z);
double complex catanh(double complex z);
float complex catanhf(float complex z);
long double complex catanhl(long double complex z);
double complex ccosh(double complex z);
float complex ccoshf(float complex z);
long double complex ccoshl(long double complex z);
double complex csinh(double complex z);
float complex csinhf(float complex z);
long double complex csinhl(long double complex z);
double complex ctanh(double complex z);
float complex ctanhf(float complex z);
long double complex ctanhl(long double complex z);
double complex cexp(double complex z);
float complex cexpf(float complex z);
long double complex cexpl(long double complex z);
double complex clog(double complex z);
float complex clogf(float complex z);
long double complex clogl(long double complex z);
double cabs(double complex z);
float cabsf(float complex z);
long double cabsl(long double complex z);
double complex cpow(double complex x, double complex y);
float complex cpowf(float complex x, float complex y);
long double complex cpowl(long double complex x, long double complex y);
double complex csqrt(double complex z);
float complex csqrtf(float complex z);
long double complex csqrtl(long double complex z);
double carg(double complex z);
float cargf(float complex z);
long double cargl(long double complex z);
double cimag(double complex z);
float cimagf(float complex z);
long double cimagl(long double complex z);
double complex CMPLX(double x, double y);
float complex CMPLXF(float x, float y);
long double complex CMPLXL(long double x, long double y);
double complex conj(double complex z);
float complex conjf(float complex z);
long double complex conjl(long double complex z);
double complex cproj(double complex z);
float complex cprojf(float complex z);
long double complex cprojl(long double complex z);
double creal(double complex z);
float crealf(float complex z);
long double creall(long double complex z);
B.3 [Character handling <ctype.h>]
int isalnum(int c);
int isalpha(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
int tolower(int c);
int toupper(int c);
B.4 [Errors <errno.h>]
EDOM EILSEQ ERANGE errno
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <errno.h>:
errno_t
B.5 [Floating-point environment <fenv.h>]
fenv_t FE_OVERFLOW FE_TOWARDZERO
fexcept_t FE_UNDERFLOW FE_UPWARD
FE_DIVBYZERO FE_ALL_EXCEPT FE_DFL_ENV
FE_INEXACT FE_DOWNWARD
FE_INVALID FE_TONEAREST
#pragma STDC FENV_ACCESS on-off-switch
#pragma STDC FENV_ROUND direction
#pragma STDC FENV_ROUND FE_DYNAMIC
int feclearexcept(int excepts);
int fegetexceptflag(fexcept_t *flagp, int excepts);
int feraiseexcept(int excepts);
int fesetexcept(int excepts);
int fesetexceptflag(const fexcept_t *flagp, int excepts);
int fetestexceptflag(const fexcept_t * flagp, int excepts);
int fetestexcept(int excepts);
int fegetmode(femode_t *modep);
int fegetround(void);
int fesetmode(const femode_t *modep);
int fesetround(int rnd);
int fegetenv(fenv_t *envp);
int feholdexcept(fenv_t *envp);
int fesetenv(const fenv_t *envp);
int feupdateenv(const fenv_t *envp);
Only if the implementation defines __STDC_IEC_60559_DFP__ :
FE_DEC_DOWNWARD FE_DEC_TONEARESTFROMZERO FE_DEC_UPWARD
FE_DEC_TONEAREST FE_DEC_TOWARDZERO
#pragma STDC FENV_DEC_ROUND dec-direction
int fe_dec_getround(void);
int fe_dec_setround(int rnd);
B.6 [Characteristics of floating types <float.h>]
FLT_ROUNDS LDBL_DIG DBL_NORM_MAX
FLT_EVAL_METHOD FLT_MIN_EXP LDBL_NORM_MAX
FLT_HAS_SUBNORM DBL_MIN_EXP FLT_EPSILON
DBL_HAS_SUBNORM LDBL_MIN_EXP DBL_EPSILON
LDBL_HAS_SUBNORM FLT_MIN_10_EXP LDBL_EPSILON
FLT_RADIX DBL_MIN_10_EXP FLT_MIN
FLT_MANT_DIG LDBL_MIN_10_EXP DBL_MIN
DBL_MANT_DIG FLT_MAX_EXP LDBL_MIN
LDBL_MANT_DIG DBL_MAX_EXP FLT_SNAN
FLT_DECIMAL_DIG LDBL_MAX_EXP DBL_SNAN
DBL_DECIMAL_DIG FLT_MAX_10_EXP LDBL_SNAN
LDBL_DECIMAL_DIG DBL_MAX_10_EXP FLT_TRUE_MIN
DECIMAL_DIG LDBL_MAX_10_EXP DBL_TRUE_MIN
FLT_IS_IEC_60559 FLT_MAX LDBL_TRUE_MIN
DBL_IS_IEC_60559 DBL_MAX INFINITY
FLT_DIG LDBL_MAX NAN
DBL_DIG FLT_NORM_MAX
B.6.1 [Characteristics of decimal floating types]
1 The following macros are provided only if the implementation defines __STDC_IEC_60559_DFP__ .
N is 32, 64 and 128.

B.15 [Variable arguments <stdarg.h>]
va_list
type va_arg(va_list ap, type);
void va_copy(va_list dest, va_list src);
void va_end(va_list ap);
void va_start(va_list ap, ...);
B.16 [Atomics <stdatomic.h>]
__STDC_NO_ATOMICS__ ATOMIC_CHAR16_T_LOCK_FREE ATOMIC_SHORT_LOCK_FREE
ATOMIC_BOOL_LOCK_FREE ATOMIC_CHAR32_T_LOCK_FREE ATOMIC_INT_LOCK_FREE
ATOMIC_CHAR_LOCK_FREE ATOMIC_WCHAR_T_LOCK_FREE ATOMIC_LONG_LOCK_FREE
ATOMIC_LLONG_LOCK_FREE atomic_ushort atomic_int_least64_t
ATOMIC_POINTER_LOCK_FREE atomic_int atomic_uint_least64_t
ATOMIC_FLAG_INIT atomic_uint atomic_int_fast8_t
memory_order atomic_long atomic_uint_fast8_t
atomic_flag atomic_ulong atomic_int_fast16_t
memory_order_relaxed atomic_llong atomic_uint_fast16_t
memory_order_consume atomic_ullong atomic_int_fast32_t
memory_order_acquire atomic_char16_t atomic_uint_fast32_t
memory_order_release atomic_char32_t atomic_int_fast64_t
memory_order_acq_rel atomic_wchar_t atomic_uint_fast64_t
memory_order_seq_cst atomic_int_least8_t atomic_intptr_t
atomic_bool atomic_uint_least8_t atomic_uintptr_t
atomic_char atomic_int_least16_t atomic_size_t
atomic_schar atomic_uint_least16_t atomic_ptrdiff_t
atomic_uchar atomic_int_least32_t atomic_intmax_t
atomic_short atomic_uint_least32_t atomic_uintmax_t
void atomic_init(volatile A *obj, C value);
type kill_dependency(type y);
void atomic_thread_fence(memory_order order);
void atomic_signal_fence(memory_order order);
bool atomic_is_lock_free(const volatile A *obj);
void atomic_store(volatile A *object, C desired);
void atomic_store_explicit(volatile A *object, C desired, memory_order order);
C atomic_load(const volatile A *object);
C atomic_load_explicit(const volatile A *object, memory_order order);
C atomic_exchange(volatile A *object, C desired);
C atomic_exchange_explicit(volatile A *object, C desired, memory_order order);
bool atomic_compare_exchange_strong(volatile A *object, C *expected, C desired);
bool atomic_compare_exchange_strong_explicit(volatile A *object, C *expected,
C desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_weak(volatile A *object, C *expected, C desired);
bool atomic_compare_exchange_weak_explicit(volatile A *object, C *expected,
C desired, memory_order success, memory_order failure);
C atomic_fetch_key(volatile A *object, M operand);
C atomic_fetch_key_explicit(volatile A *object, M operand, memory_order order);
bool atomic_flag_test_and_set(volatile atomic_flag *object);
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object,
memory_order order);
void atomic_flag_clear(volatile atomic_flag *object);
void atomic_flag_clear_explicit(volatile atomic_flag *object,
memory_order order);
B.17 [Bit and byte utilities <stdbit.h>]
__STDC_ENDIAN_BIG__ __STDC_ENDIAN_LITTLE__ __STDC_ENDIAN_NATIVE__
int stdc_leading_zerosuc(unsigned char value);
int stdc_leading_zerosus(unsigned short value);
int stdc_leading_zerosui(unsigned int value);
int stdc_leading_zerosul(unsigned long value);
int stdc_leading_zerosull(unsigned long long value);
generic_return_type stdc_leading_zeros(generic_value_type value);
int stdc_leading_onesuc(unsigned char value);
int stdc_leading_onesus(unsigned short value);
int stdc_leading_onesui(unsigned int value);
int stdc_leading_onesul(unsigned long value);
int stdc_leading_onesull(unsigned long long value);
generic_return_type stdc_leading_ones(generic_value_type value);
int stdc_trailing_zerosuc(unsigned char value);
int stdc_trailing_zerosus(unsigned short value);
int stdc_trailing_zerosui(unsigned int value);
int stdc_trailing_zerosul(unsigned long value);
int stdc_trailing_zerosull(unsigned long long value);
generic_return_type stdc_trailing_zeros(generic_value_type value);
int stdc_trailing_onesuc(unsigned char value);
int stdc_trailing_onesus(unsigned short value);
int stdc_trailing_onesui(unsigned int value);
int stdc_trailing_onesul(unsigned long value);
int stdc_trailing_onesull(unsigned long long value);
generic_return_type stdc_trailing_ones(generic_value_type value);
int stdc_first_leading_zerouc(unsigned char value);
int stdc_first_leading_zerous(unsigned short value);
int stdc_first_leading_zeroui(unsigned int value);
int stdc_first_leading_zeroul(unsigned long value);
int stdc_first_leading_zeroull(unsigned long long value);
generic_return_type stdc_first_leading_zero(generic_value_type value);
int stdc_first_leading_oneuc(unsigned char value);
int stdc_first_leading_oneus(unsigned short value);
int stdc_first_leading_oneui(unsigned int value);
int stdc_first_leading_oneul(unsigned long value);
int stdc_first_leading_oneull(unsigned long long value);
generic_return_type stdc_first_leading_one(generic_value_type value);
int stdc_first_trailing_zerouc(unsigned char value);
int stdc_first_trailing_zerous(unsigned short value);
int stdc_first_trailing_zeroui(unsigned int value);
int stdc_first_trailing_zeroul(unsigned long value);
int stdc_first_trailing_zeroull(unsigned long long value);
generic_return_type stdc_first_trailing_zero(generic_value_type value);
int stdc_first_trailing_oneuc(unsigned char value);
int stdc_first_trailing_oneus(unsigned short value);
int stdc_first_trailing_oneui(unsigned int value);
int stdc_first_trailing_oneul(unsigned long value);
int stdc_first_trailing_oneull(unsigned long long value);
generic_return_type stdc_first_trailing_one(generic_value_type value);
int stdc_count_onesuc(unsigned char value);
int stdc_count_onesus(unsigned short value);
int stdc_count_onesui(unsigned int value);
int stdc_count_onesul(unsigned long value);
int stdc_count_onesull(unsigned long long value);
generic_return_type stdc_count_ones(generic_value_type value);
int stdc_count_zerosuc(unsigned char value);
int stdc_count_zerosus(unsigned short value);
int stdc_count_zerosui(unsigned int value);
int stdc_count_zerosul(unsigned long value);
int stdc_count_zerosull(unsigned long long value);
generic_return_type stdc_count_zeros(generic_value_type value);
bool stdc_has_single_bituc(unsigned char value);
bool stdc_has_single_bitus(unsigned short value);
bool stdc_has_single_bitui(unsigned int value);
bool stdc_has_single_bitul(unsigned long value);
bool stdc_has_single_bitull(unsigned long long value);
bool stdc_has_single_bit(generic_value_type value);
int stdc_bit_widthuc(unsigned char value);
int stdc_bit_widthus(unsigned short value);
int stdc_bit_widthui(unsigned int value);
int stdc_bit_widthul(unsigned long value);
int stdc_bit_widthull(unsigned long long value);
generic_return_type stdc_bit_width(generic_value_type value);
unsigned char stdc_bit_flooruc(unsigned char value);
unsigned short stdc_bit_floorus(unsigned short value);
unsigned int stdc_bit_floorui(unsigned int value);
unsigned long stdc_bit_floorul(unsigned long value);
unsigned long long stdc_bit_floorull(unsigned long long value);
generic_value_type stdc_bit_floor(generic_value_type value);
unsigned char stdc_bit_ceiluc(unsigned char value);
unsigned short stdc_bit_ceilus(unsigned short value);
unsigned int stdc_bit_ceilui(unsigned int value);
unsigned long stdc_bit_ceilul(unsigned long value);
unsigned long long stdc_bit_ceilull(unsigned long long value);
generic_value_type stdc_bit_ceil(generic_value_type value);
B.18 [Boolean type and values <stdbool.h>]
__bool_true_false_are_defined
B.19 [Common definitions <stddef.h>]
ptrdiff_t size_t wchar_t
nullptr_t max_align_t NULL
offsetof(type, member-designator)
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <stddef.h>:
rsize_t
B.20 [Integer types <stdint.h>]
intN_t UINT_LEASTN_MAX PTRDIFF_MAX
uintN_t UINT_LEASTN_WIDTH SIG_ATOMIC_MIN
int_leastN_t INT_FASTN_MIN SIG_ATOMIC_MAX
uint_leastN_t INT_FASTN_MAX SIG_ATOMIC_WIDTH
int_fastN_t INT_FASTN_WIDTH SIZE_MAX
uint_fastN_t UINT_FASTN_MAX SIZE_WIDTH
intptr_t UINT_FASTN_WIDTH WCHAR_MIN
uintptr_t INTPTR_MIN WCHAR_MAX
intmax_t INTPTR_MAX WCHAR_WIDTH
uintmax_t INTPTR_WIDTH WINT_MIN
INTN_MIN UINTPTR_MAX WINT_MAX
INTN_MAX UINTPTR_WIDTH WINT_WIDTH
INTN_WIDTH INTMAX_MIN INTN_C( value )
UINTN_MAX INTMAX_MAX UINTN_C( value )
UINTN_WIDTH INTMAX_WIDTH INTMAX_C( value )
INT_LEASTN_MIN UINTMAX_MAX UINTMAX_C( value )
INT_LEASTN_MAX UINTMAX_WIDTH
INT_LEASTN_WIDTH PTRDIFF_MIN
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <stdint.h>:
RSIZE_MAX
B.21 [Input/output <stdio.h>]
size_t _IONBF SEEK_CUR stdout
_PRINTF_NAN_LEN_MAX
FILE BUFSIZ SEEK_END
fpos_t EOF SEEK_SET
NULL FOPEN_MAX TMP_MAX
_IOFBF FILENAME_MAX stderr
_IOLBF L_tmpnam stdin
int remove(const char *filename);
int rename(const char *old, const char *new);
FILE *tmpfile(void);
char *tmpnam(char *s);
int fclose(FILE *stream);
int fflush(FILE *stream);
FILE *fopen(const char * restrict filename, const char * restrict mode);
FILE *freopen(const char * restrict filename, const char * restrict mode,
FILE * restrict stream);
void setbuf(FILE * restrict stream, char * restrict buf);
int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
int printf(const char * restrict format, ...);
int scanf(const char * restrict format, ...);
int snprintf(char * restrict s, size_t n, const char * restrict format, ...);
int sprintf(char * restrict s, const char * restrict format, ...);
int sscanf(const char * restrict s, const char * restrict format, ...);
int vfprintf(FILE * restrict stream, const char * restrict format, va_list arg);
int vfscanf(FILE * restrict stream, const char * restrict format, va_list arg);
int vprintf(const char * restrict format, va_list arg);
int vscanf(const char * restrict format, va_list arg);
int vsnprintf(char * restrict s, size_t n, const char * restrict format, va_list arg);
int vsprintf(char * restrict s, const char * restrict format, va_list arg);
int vsscanf(const char * restrict s, const char * restrict format, va_list arg);
int fgetc(FILE *stream);
char *fgets(char * restrict s, int n, FILE * restrict stream);
int fputc(int c, FILE *stream);
int fputs(const char * restrict s, FILE * restrict stream);
int getc(FILE *stream);
int getchar(void);
int putc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
int ungetc(int c, FILE *stream);
size_t fread(void * restrict ptr, size_t size, size_t nmemb,
FILE * restrict stream);
size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb,
FILE * restrict stream);
int fgetpos(FILE * restrict stream, fpos_t * restrict pos);
int fseek(FILE *stream, long int offset, int whence);
int fsetpos(FILE *stream, const fpos_t *pos);
long int ftell(FILE *stream);
void rewind(FILE *stream);
void clearerr(FILE *stream);
int feof(FILE *stream);
int ferror(FILE *stream);
void perror(const char *s);
int fprintf(FILE * restrict stream, const char * restrict format, ...);
int fscanf(FILE * restrict stream, const char * restrict format, ...);
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <stdio.h>:
L_tmpnam_s TMP_MAX_S errno_t rsize_t
errno_t tmpfile_s(FILE * restrict * restrict streamptr);
errno_t tmpnam_s(char *s, rsize_t maxsize);
errno_t fopen_s(FILE * restrict * restrict streamptr,
const char * restrict filename, const char * restrict mode);
errno_t freopen_s(FILE * restrict * restrict newstreamptr,
const char * restrict filename, const char * restrict mode,
FILE * restrict stream);
int fprintf_s(FILE * restrict stream, const char * restrict format, ...);
int fscanf_s(FILE * restrict stream, const char * restrict format, ...);
int printf_s(const char * restrict format, ...);
int scanf_s(const char * restrict format, ...);
int snprintf_s(char * restrict s, rsize_t n, const char * restrict format, ...);
int sprintf_s(char * restrict s, rsize_t n, const char * restrict format, ...);
int sscanf_s(const char * restrict s, const char * restrict format, ...);
int vfprintf_s(FILE *restrict stream, const char *restrict format, va_list arg);
int vfscanf_s(FILE *restrict stream, const char *restrict format, va_list arg);
int vprintf_s(const char * restrict format, va_list arg);
int vscanf_s(const char * restrict format, va_list arg);
int vsnprintf_s(char *restrict s, rsize_t n, const char *restrict format,
va_list arg);
int vsprintf_s(char * restrict s, rsize_t n, const char * restrict format,
va_list arg);
int vsscanf_s(const char *restrict s, const char *restrict format, va_list arg);
char *gets_s(char *s, rsize_t n);
B.22 [General utilities <stdlib.h>]
size_t div_t lldiv_t EXIT_FAILURE RAND_MAX
wchar_t ldiv_t NULL EXIT_SUCCESS MB_CUR_MAX
double atof(const char *nptr);
int atoi(const char *nptr);
long int atol(const char *nptr);
long long int atoll(const char *nptr);
int strfromd(char *restrict s, size_t n, const char *restrict format, double fp);
int strfromf(char *restrict s, size_t n, const char *restrict format, float fp);
int strfroml(char *restrict s, size_t n, const char *restrict format, long double fp);
double strtod(const char *restrict nptr, char **restrict endptr);
float strtof(const char *restrict nptr, char **restrict endptr);
long double strtold(const char *restrict nptr, char **restrict endptr);
long int strtol(const char *restrict nptr, char **restrict endptr, int base);
long long int strtoll(const char *restrict nptr, char **restrict endptr, int base);
unsigned long int strtoul(const char *restrict nptr, char **restrict endptr, int base);
unsigned long long int strtoull(const char *restrict nptr, char **restrict endptr, int
base);
int rand(void);
void srand(unsigned int seed);
void *aligned_alloc(size_t alignment, size_t size);
void *calloc(size_t nmemb, size_t size);
void free(void *ptr);
void free_sized(void *ptr, size_t size);
void free_aligned_sized(void *ptr, size_t alignment, size_t size);
void *malloc(size_t size);
void *realloc(void *ptr, size_t size);
[[noreturn]] void abort(void);
int atexit(void (*func)(void));
int at_quick_exit(void (*func)(void));
[[noreturn]] void exit(int status);
[[noreturn]] void _Exit(int status);
char *getenv(const char *name);
[[noreturn]] void quick_exit(int status);
int system(const char *string);
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
int abs(int j);
long int labs(long int j);
long long int llabs(long long int j);
div_t div(int numer, int denom);
ldiv_t ldiv(long int numer, long int denom);
lldiv_t lldiv(long long int numer, long long int denom);
int mblen(const char *s, size_t n);
int mbtowc(wchar_t * restrict pwc, const char * restrict s, size_t n);
int wctomb(char *s, wchar_t wc);
size_t mbstowcs(wchar_t * restrict pwcs, const char * restrict s, size_t n);
size_t wcstombs(char * restrict s, const wchar_t * restrict pwcs, size_t n);
size_t memalignment(const void * p);
Only if the implementation defines __STDC_IEC_60559_DFP__ :
int strfromd32(char*restrict s, size_t n, const char*restrict format, _Decimal32 fp);
int strfromd64(char*restrict s, size_t n, const char*restrict format, _Decimal64 fp);
int strfromd128(char*restrict s, size_t n, const char*restrict format, _Decimal128 fp);
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <stdlib.h>:
errno_t rsize_t constraint_handler_t
constraint_handler_t set_constraint_handler_s(constraint_handler_t handler);
void abort_handler_s(const char * restrict msg, void * restrict ptr,
errno_t error);
void ignore_handler_s(const char * restrict msg, void * restrict ptr,
errno_t error);
errno_t getenv_s(size_t * restrict len, char * restrict value, rsize_t maxsize,
const char * restrict name);
void *bsearch_s(const void *key, QVoid *base, rsize_t nmemb, rsize_t size,
int (*compar)(const void *k, const void *y, void *context),
void *context);
errno_t qsort_s(void *base, rsize_t nmemb, rsize_t size,
int (*compar)(const void *x, const void *y, void *context),
void *context);
errno_t wctomb_s(int *restrict status, char *restrict s, rsize_t smax,
wchar_t wc);
errno_t mbstowcs_s(size_t *restrict retval, wchar_t *restrict dst,
rsize_t dstmax, const char * restrict src, rsize_t len);
errno_t wcstombs_s(size_t * restrict retval, char * restrict dst, rsize_t dstmax,
const wchar_t * restrict src, rsize_t len);
B.23 [_Noreturn <stdnoreturn.h>]
noreturn
B.24 [ckd_ Checked Integer Operations <stdckdint.h>]
bool ckd_add(type1 *result, type2 a, type3 b);
bool ckd_sub(type1 *result, type2 a, type3 b);
bool ckd_mul(type1 *result, type2 a, type3 b);
B.25 [String handling <string.h>]
size_t NULL
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
void *memccpy(void * restrict s1, const void * restrict s2, int c, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
char *strcpy(char * restrict s1, const char * restrict s2);
char *strncpy(char * restrict s1, const char * restrict s2, size_t n);
char *strdup(const char *s);
char *strndup(const char *s, size_t size);
char *strcat(char * restrict s1, const char * restrict s2);
char *strncat(char * restrict s1, const char * restrict s2, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strcoll(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n);
QVoid *memchr(QVoid *s, int c, size_t n);
QChar *strchr(QChar *s, int c);
size_t strcspn(const char *s1, const char *s2);
QChar *strpbrk(QChar *s1, const char *s2);
QChar *strrchr(QChar *s, int c);
size_t strspn(const char *s1, const char *s2);
QChar *strstr(QChar *s1, const char *s2);
char *strtok(char * restrict s1, const char * restrict s2);
void *memset(void *s, int c, size_t n);
void *memset_explicit(void *s, int c, size_t n);
char *strerror(int errnum);
size_t strlen(const char *s);
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <string.h>:
errno_t rsize_t
errno_t memcpy_s(void * restrict s1, rsize_t s1max, const void * restrict s2,
rsize_t n);
errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n);
errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2);
errno_t strncpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2,
rsize_t n);
errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2);
errno_t strncat_s(char * restrict s1, rsize_t s1max, const char * restrict s2,
rsize_t n);
char *strtok_s(char * restrict s1, rsize_t * restrict s1max,
const char * restrict s2, char ** restrict ptr);
errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n)
errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum);
size_t strerrorlen_s(errno_t errnum);
size_t strnlen_s(const char *s, size_t maxsize);
B.26 [Type-generic math <tgmath.h>]
acos atanpi fmin logb tanpi
asin cbrt fminimum logp1 tgamma
atan ceil fminimum_mag lrint trunc
acosh compoundn fminimum_num lround ufromfpx
asinh copysign fminimum_mag_num nearbyint ufromfp
atanh cospi fmod nextafter fadd
cos erfc frexp nextdown dadd
sin erf fromfpx nexttoward fsub
tan exp10m1 fromfp nextup dsub
cosh exp10 hypot pown fmul
sinh exp2m1 ilogb powr dmul
tanh exp2 ldexp remainder fdiv
exp expm1 lgamma remquo ddiv
log fdim llogb rint ffma
pow floor llrint rootn dfma
sqrt fmax llround roundeven fsqrt
fabs fmaximum log10p1 round dsqrt
acospi fmaximum_mag log10 rsqrt
asinpi fmaximum_num log1p scalbln
atan2pi fmaximum_mag_num log2p1 scalbn
atan2 fma log2 sinpi
Only if the implementation does not define __STDC_NO_COMPLEX__ :
carg cimag conj cproj creal
Only if the implementation defines __STDC_IEC_60559_DFP__ :
d32add d64sub d32div d64fma quantize llquantexp
d64add d32mul d64div d32sqrt samequantum
d32sub d64mul d32fma d64sqrt quantum
B.27 [Threads <threads.h>]
__STDC_NO_THREADS__ mtx_t thrd_timedout
thread_local tss_dtor_t thrd_success
ONCE_FLAG_INIT thrd_start_t thrd_busy
TSS_DTOR_ITERATIONS once_flag thrd_error
cnd_t mtx_plain thrd_nomem
thrd_t mtx_recursive
tss_t mtx_timed
void call_once(once_flag *flag, void (*func)(void));
int cnd_broadcast(cnd_t *cond);
void cnd_destroy(cnd_t *cond);
int cnd_init(cnd_t *cond);
int cnd_signal(cnd_t *cond);
int cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mtx,
const struct timespec *restrict ts);
int cnd_wait(cnd_t *cond, mtx_t *mtx);
void mtx_destroy(mtx_t *mtx);
int mtx_init(mtx_t *mtx, int type);
int mtx_lock(mtx_t *mtx);
int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts);
int mtx_trylock(mtx_t *mtx);
int mtx_unlock(mtx_t *mtx);
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
thrd_t thrd_current(void);
int thrd_detach(thrd_t thr);
int thrd_equal(thrd_t thr0, thrd_t thr1);
[[noreturn]] void thrd_exit(int res);
int thrd_join(thrd_t thr, int *res);
int thrd_sleep(const struct timespec *duration, struct timespec *remaining);
void thrd_yield(void);
int tss_create(tss_t *key, tss_dtor_t dtor);
void tss_delete(tss_t key);
void *tss_get(tss_t key);
int tss_set(tss_t key, void *val);
B.28 [Date and time <time.h>]
NULL size_t struct timespec
CLOCKS_PER_SEC clock_t struct tm
TIME_UTC time_t
clock_t clock(void);
double difftime(time_t time1, time_t time0);
time_t mktime(struct tm *timeptr);
time_t timegm(struct tm *timeptr);
time_t time(time_t *timer);
int timespec_get(struct timespec *ts, int base);
int timespec_getres(struct timespec *ts, int base);
[[deprecated]] char *asctime(const struct tm *timeptr);
[[deprecated]] char *ctime(const time_t *timer);
struct tm *gmtime(const time_t *timer);
struct tm *gmtime_r(const time_t *timer, struct tm *buf);
struct tm *localtime(const time_t *timer);
struct tm *localtime_r(const time_t *timer, struct tm *buf);
size_t strftime(char * restrict s, size_t maxsize, const char * restrict format,
const struct tm * restrict timeptr);
Only if supported by the implementation:
TIME_MONOTONIC
TIME_ACTIVE
Only if threads are supported and it is supported by the implementation:
TIME_THREAD_ACTIVE
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <time.h>:
errno_t rsize_t
errno_t asctime_s(char *s, rsize_t maxsize, const struct tm *timeptr);
errno_t ctime_s(char *s, rsize_t maxsize, const time_t *timer);
struct tm *gmtime_s(const time_t * restrict timer, struct tm * restrict result);
struct tm *localtime_s(const time_t *restrict timer, struct tm *restrict result);
B.29 [Unicode utilities <uchar.h>]
mbstate_t size_t char16_t char32_t
size_t mbrtoc8(char8_t * restrict pc8, const char * restrict s, size_t n,
mbstate_t * restrict ps);
size_t c8rtomb(char * restrict s, char8_t c8, mbstate_t * restrict ps);
size_t mbrtoc16(char16_t * restrict pc16, const char * restrict s, size_t n,
mbstate_t * restrict ps);
size_t c16rtomb(char * restrict s, char16_t c16, mbstate_t * restrict ps);
size_t mbrtoc32(char32_t * restrict pc32, const char * restrict s, size_t n,
mbstate_t * restrict ps);
size t c32rtomb(char * restrict s, char32_t c32, mbstate_t * restrict ps);
_
B.30 [Extended multibyte/wide character utilities <wchar.h>]
wchar_t wint_t WCHAR_MAX
size_t struct tm WCHAR_MIN
mbstate_t NULL WEOF
int fwprintf(FILE * restrict stream, const wchar_t * restrict format, ...);
int fwscanf(FILE * restrict stream, const wchar_t * restrict format, ...);
int swprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format,
...);
int swscanf(const wchar_t * restrict s, const wchar_t * restrict format, ...);
int vfwprintf(FILE * restrict stream, const wchar_t * restrict format,
va_list arg);
int vfwscanf(FILE * restrict stream, const wchar_t * restrict format,
va_list arg);
int vswprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format,
va_list arg);
int vswscanf(const wchar_t * restrict s, const wchar_t * restrict format,
va_list arg);
int vwprintf(const wchar_t * restrict format, va_list arg);
int vwscanf(const wchar_t * restrict format, va_list arg);
int wprintf(const wchar_t * restrict format, ...);
int wscanf(const wchar_t * restrict format, ...);
wint_t fgetwc(FILE *stream);
wchar_t *fgetws(wchar_t * restrict s, int n, FILE * restrict stream);
wint_t fputwc(wchar_t c, FILE *stream);
int fputws(const wchar_t * restrict s, FILE * restrict stream);
int fwide(FILE *stream, int mode);
wint_t getwc(FILE *stream);
wint_t getwchar(void);
wint_t putwc(wchar_t c, FILE *stream);
wint_t putwchar(wchar_t c);
wint_t ungetwc(wint_t c, FILE *stream);
long int wcstol(const wchar_t * restrict nptr, wchar_t ** restrict endptr,
int base);
long long int wcstoll(const wchar_t * restrict nptr, wchar_t ** restrict endptr,
int base);
unsigned long int wcstoul(const wchar_t * restrict nptr,
wchar_t ** restrict endptr, int base);
unsigned long long int wcstoull(const wchar_t * restrict nptr,
wchar_t ** restrict endptr, int base);
wchar t *wcscpy(wchar_t * restrict s1, const wchar_t * restrict s2);
_
wchar_t *wcsncpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
wchar_t *wmemcpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2, size_t n);
wchar_t *wcscat(wchar_t * restrict s1, const wchar_t * restrict s2);
wchar_t *wcsncat(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
int wcscmp(const wchar_t *s1, const wchar_t *s2);
int wcscoll(const wchar_t *s1, const wchar_t *s2);
int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n);
size_t wcsxfrm(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n);
int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n);
QWchar_t *wcschr(QWchar_t *s, wchar_t c);
size_t wcscspn(const wchar_t *s1, const wchar_t *s2);
QWchar_t *wcspbrk(QWchar_t *s1, const wchar_t *s2);
QWchar_t *wcsrchr(const wchar_t *s, wchar_t c);
size_t wcsspn(const wchar_t *s1, const wchar_t *s2);
QWchar_t *wcsstr(QWchar_t *s1, const wchar_t *s2);
wchar_t *wcstok(wchar_t * restrict s1, const wchar_t * restrict s2,
wchar_t ** restrict ptr);
QWchar_t *wmemchr(QWchar_t *s, wchar_t c, size_t n);
size_t wcslen(const wchar_t *s);
wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n);
size_t wcsftime(wchar_t * restrict s, size_t maxsize,
const wchar_t * restrict format, const struct tm * restrict timeptr);
wint_t btowc(int c);
int wctob(wint_t c);
int mbsinit(const mbstate_t *ps);
size_t mbrlen(const char * restrict s, size_t n, mbstate_t * restrict ps);
size_t mbrtowc(wchar_t * restrict pwc, const char * restrict s, size_t n,
mbstate_t * restrict ps);
size_t wcrtomb(char * restrict s, wchar_t wc, mbstate_t * restrict ps);
size_t mbsrtowcs(wchar_t * restrict dst, const char ** restrict src, size_t len,
mbstate_t * restrict ps);
size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len,
mbstate_t * restrict ps);
Only if the implementation defines __STDC_LIB_EXT1__ and additionally the user code defines
__STDC_WANT_LIB_EXT1__ before any inclusion of <wchar.h>:
errno_t rsize_t
int fwprintf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
int fwscanf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
int snwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format,
...);
int swprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format,
...);
int swscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, ...);
int vfwprintf_s(FILE * restrict stream, const wchar_t * restrict format,
va_list arg);
int vfwscanf_s(FILE * restrict stream, const wchar_t * restrict format,
va_list arg);
int vsnwprintf_s(wchar_t *restrict s, rsize_t n, const wchar_t *restrict format,
va_list arg);
int vswprintf_s(wchar_t *restrict s, rsize_t n, const wchar_t *restrict format,
va_list arg);
int vswscanf_s(const wchar_t * restrict s, const wchar_t * restrict format,
va_list arg);
int vwprintf_s(const wchar_t * restrict format, va_list arg);
int vwscanf_s(const wchar_t * restrict format, va_list arg);
int wprintf_s(const wchar_t * restrict format, ...);
int wscanf_s(const wchar_t * restrict format, ...);
errno_t wcscpy_s(wchar_t *restrict s1, rsize_t s1max,
const wchar_t *restrict s2);
errno t wcsncpy_s(wchar_t * restrict s1, rsize_t s1max,
_
const wchar_t * restrict s2, rsize_t n);
errno_t wmemcpy_s(wchar_t *restrict s1, rsize_t s1max,
const wchar_t *restrict s2, rsize_t n);
errno_t wmemmove_s(wchar_t *s1, rsize_t s1max, const wchar_t *s2, rsize_t n);
errno_t wcscat_s(wchar_t * restrict s1, rsize_t s1max,
const wchar_t * restrict s2);
errno_t wcsncat_s(wchar_t * restrict s1, rsize_t s1max,
const wchar_t * restrict s2, rsize_t n);
wchar t *wcstok_s(wchar_t * restrict s1, rsize_t * restrict s1max,
_
const wchar_t * restrict s2, wchar_t ** restrict ptr);
size_t wcsnlen_s(const wchar_t *s, size_t maxsize);
errno_t wcrtomb_s(size_t * restrict retval, char * restrict s, rsize_t smax,
wchar_t wc, mbstate_t * restrict ps);
errno_t mbsrtowcs_s(size_t * restrict retval, wchar_t * restrict dst,
rsize_t dstmax, const char ** restrict src, rsize_t len,
mbstate_t * restrict ps);
errno_t wcsrtombs_s(size_t * restrict retval, char * restrict dst,
rsize_t dstmax, const wchar_t ** restrict src, rsize_t len,
mbstate_t * restrict ps);
B.31 [Wide character classification and mapping utilities <wctype.h>]
wint_t wctrans_t wctype_t WEOF
int iswalnum(wint_t wc);
int iswalpha(wint_t wc);
int iswblank(wint_t wc);
int iswcntrl(wint_t wc);
int iswdigit(wint_t wc);
int iswgraph(wint_t wc);
int iswlower(wint_t wc);
int iswprint(wint_t wc);
int iswpunct(wint_t wc);
int iswspace(wint_t wc);
int iswupper(wint_t wc);
int iswxdigit(wint_t wc);
int iswctype(wint_t wc, wctype_t desc);
wctype_t wctype(const char *property);
wint_t towlower(wint_t wc);
wint_t towupper(wint_t wc);
wint_t towctrans(wint_t wc, wctrans_t desc);
wctrans_t wctrans(const char *property);
C. [Annex C (informative) Sequence points]
1 The following are the sequence points described in <IP_ADDRESS>:
— Between the evaluations of the function designator and actual arguments in a function call
and the actual call. (<IP_ADDRESS>).
— Between the evaluations of the first and second operands of the following operators: logical
AND && (6.5.13); logical OR || (6.5.14); comma , (6.5.17).
— Between the evaluations of the first operand of the conditional ?: operator and whichever of
the second and third operands is evaluated (6.5.15).
— Between the evaluation of a full expression and the next full expression to be evaluated. The
following are full expressions: a full declarator for a variably modified type; an initializer that
is not part of a compound literal (6.7.10); the expression in an expression statement (6.8.3); the
controlling expression of a selection statement (if or switch) (6.8.4); the controlling expression
of a while or do statement (6.8.5); each of the (optional) expressions of a for statement (<IP_ADDRESS>);
the (optional) expression in a return statement (<IP_ADDRESS>).
— Immediately before a library function returns (7.1.4).
— After the actions associated with each formatted input/output function conversion specifier
(7.23.6, 7.31.2).
— Immediately before and immediately after each call to a comparison function, and also between
any call to a comparison function and any movement of the objects passed as arguments to
that call (7.24.5).
D. [Annex D (informative) Universal character names for identifiers]
1 This subclause describes the choices made in application of UAX #31 ("Unicode Identifier and
Pattern Syntax") to C of the requirements from UAX #31 and how they do or do not apply to C.
For UAX #31, C conforms by meeting the requirements "Default Identifiers" (D.1) and "Equivalent
Normalized Identifiers" (D.1). The other requirements, also listed below, are either alternatives not
taken or do not apply to C.
D.1 [Default Identifiers]
1 UAX #31 specifies a default syntax for identifiers based on properties from the Unicode Character
Database, UAX #44. The general syntax is
<Identifier> := <Start> <Continue>* (<Medial> <Continue>+)*
where <Start> has the XID_Start property, <Continue> has the XID_Continue property, and
<Medial> is a list of characters permitted between continue characters. For C we add the character
U+005F, LOW LINE, or _, to the set of permitted Start characters, the Medial set is empty, and the
Continue characters are unmodified. In the grammar used in UAX #31, this is
<Identifier> := <Start> <Continue>*
<Start> := XID_Start + U+005F
<Continue> := <Start> + XID_Continue
This is described in the C grammar (<IP_ADDRESS>), where identifier is formed from identifier-start or identifier
followed by identifier-continue.
D.1.1 [Restricted Format Characters]
1 If an implementation of UAX #31 wishes to allow format characters such as ZERO WIDTH JOINER
or ZERO WIDTH NON-JOINER it must define a profile allowing them, or describe precisely which
combinations are permitted.
2 C does not allow format characters in identifiers, so this does not apply.
D.1.2 [Stable Identifiers]
1 An implementation of UAX #31 may choose to guarantee that identifiers are stable across versions
of the Unicode Standard. Once a string qualifies as an identifier it does so in all future versions.
C does not make this guarantee, except to the extent that UAX #31 guarantees the stability of the
XID_Start and XID_Continue properties.
D.2 [Immutable Identifiers]
1 An implementation may choose to guarantee that the set of identifiers will never change by fixing
the set of code points allowed in identifiers forever.
2 C does not choose to make this guarantee. As scripts are added to Unicode, additional characters in
those scripts may become available for use in identifiers.
D.3 [Pattern_White_Space and Pattern_Syntax Characters]
1 UAX #31 describes how languages that use or interpret patterns of characters, such as regular
expressions or number formats, may describe that syntax with Unicode properties.
2 C does not do this as part of the language, deferring to library components for such usage of patterns.
This requirement does not apply to C.
D.4 [Equivalent Normalized Identifiers]
1 UAX #31 requires that implementations describe how identifiers are compared and considered
equivalent.
2 C requires that identifiers be in Normalization Form C and therefore identifiers that compare the
same under NFC are equivalent. This is described in subclause 6.4.2.
D.5 [Equivalent Case-Insensitive Identifiers]
1 C considers case to be significant in identifier comparison, and does not do any case folding. This
requirement does not apply to C
D.6 [Filtered Normalized Identifiers]
1 If any characters are excluded from normalization, UAX #31 requires a precise specification of those
exclusions.
2 C does not make any such exclusions.
D.7 [Filtered Case-Insensitive Identifiers]
1 C identifiers are case sensitive, and therefore this requirement does not apply.
D.8 [Hashtag Identifiers]
1 There are no hashtags in C, so this requirement does not apply.
E. [Annex E (informative) Implementation limits]
1 The contents of the header <limits.h> are given below. The values shall all be constant expressions
suitable for use in #if preprocessing directives.  The numbers in the table are only given as indications for the values and do not represent suitable expressions
to be used for these macros.
4 The contents of the header <float.h> are given below. All integer values, except FLT_ROUNDS, shall
be constant expressions suitable for use in #if preprocessing directives; all floating values shall be
constant expressions. The components are described further in <IP_ADDRESS>.2 and <IP_ADDRESS>.3.
5 The values given in the following list shall be replaced by implementation-defined expressions:
#define FLT_EVAL_METHOD
#define FLT_ROUNDS
#ifdef __STDC_IEC_60559_DFP__
#define DEC_EVAL_METHOD
#endif
6 The values given in the following list shall be replaced by implementation-defined constant ex-
pressions that are greater or equal in magnitude (absolute value) to those shown, with the same
sign:
#define DBL_DECIMAL_DIG 10
#define DBL_DIG 10
#define DBL_MANT_DIG
#define DBL_MAX_10_EXP +37
#define DBL_MAX_EXP
#define DBL_MIN_10_EXP -37
#define DBL_MIN_EXP
#define DECIMAL_DIG 10
#define FLT_DECIMAL_DIG 6
#define FLT_DIG 6
#define FLT_MANT_DIG
#define FLT_MAX_10_EXP +37
#define FLT_MAX_EXP
#define FLT_MIN_10_EXP -37
#define FLT_MIN_EXP
#define FLT_RADIX 2
#define LDBL_DECIMAL_DIG 10
#define LDBL_DIG 10
#define LDBL_MANT_DIG
#define LDBL_MAX_10_EXP +37
#define LDBL_MAX_EXP
#define LDBL_MIN_10_EXP -37
#define LDBL_MIN_EXP
7 The values given in the following list shall be replaced by implementation-defined constant expres-
sions with values that are greater than or equal to those shown:
#define DBL_MAX 1E+37
#define DBL_NORM_MAX 1E+37
#define FLT_MAX 1E+37
#define FLT_NORM_MAX 1E+37
#define LDBL_MAX 1E+37
#define LDBL_NORM_MAX 1E+37
8 The values given in the following list shall be replaced by implementation-defined constant expres-
sions with (positive) values that are less than or equal to those shown:
#define DBL_EPSILON 1E-9
#define DBL_MIN 1E-37
#define FLT_EPSILON 1E-5
#define FLT_MIN 1E-37
#define LDBL_EPSILON 1E-9
#define LDBL_MIN 1E-37
9 If the implementation supports decimal floating types, the following macros provide the parameters
of these types as exact values.
#ifdef __STDC_IEC_60559_DFP__
#define DEC32_EPSILON 1E-6DF
#define DEC32_MANT_DIG 7
#define DEC32_MAX 9.999999E96DF
#define DEC32_MAX_EXP 97
#define DEC32_MIN 1E-95DF
#define DEC32_MIN_EXP -94
#define DEC32_TRUE_MIN 0.000001E-95DF
#define DEC64_EPSILON 1E-15DD
#define DEC64_MANT_DIG 16
#define DEC64_MAX 9.999999999999999E384DD
#define DEC64_MAX_EXP 385
#define DEC64_MIN 1E-383DD
#define DEC64_MIN_EXP -382
#define DEC64_TRUE_MIN 0.000000000000001E-383DD
#define DEC128_EPSILON 1E-33DL
#define DEC128_MANT_DIG 34
#define DEC128_MAX 9.999999999999999999999999999999999E6144DL
#define DEC128_MAX_EXP 6145
#define DEC128_MIN 1E-6143DL
#define DEC128_MIN_EXP -6142
#define DEC128_TRUE_MIN 0.000000000000000000000000000000001E-6143DL
#endif
F. [Annex F (normative) IEC 60559 floating-point arithmetic]
F.1 [Introduction]
1 This annex specifies C language support for the IEC 60559 floating-point standard. The IEC 60559
floating-point standard is specifically Floating-point arithmetic (ISO/IEC 60559:2020), also designated
as IEEE Standard for Floating-Point Arithmetic (IEEE 754–2019). IEC 60559 generally refers to the
floating-point standard, as in IEC 60559 operation, IEC 60559 format, etc.
2 The IEC 60559 floating-point standard specifies decimal, as well as binary, floating-point arithmetic.
It supersedes IEEE Standard for Radix-Independent Floating-Point Arithmetic (ANSI/IEEE 854–1987)
which generalized the binary arithmetic standard (IEEE 754-1985) to remove dependencies on radix
and word length.
3 An implementation that defines __STDC_IEC_60559_BFP__ to 202311L shall conform to the specifi-
cations in this annex for binary floating-point arithmetic and shall also define __STDC_IEC_559__
to 1.[435]
Footnote 435) Implementations that do not define either of __STDC_IEC_60559_BFP__ and __STDC_IEC_559__ are not required to
conform to these specifications. New code should not use the obsolescent macro __STDC_IEC_559__ to test for conformance
to this annex.
4 An implementation that defines __STDC_IEC_60559_DFP__ to 202311L shall conform to the
specifications for decimal floating-point arithmetic in the following subclauses of this annex:
— F.2.1 Infinities and NaNs
— F.3 Operations
— F.4 Floating to integer conversions
— F.6 The return statement
— F.7 Contracted expressions
— F.8 Floating-point environment
— F.9 Optimization
— F.10 Mathematics <math.h> and <tgmath.h>
For the purpose of specifying these conformance requirements, the macros, functions, and values
mentioned in the subclauses listed above are understood to refer to the corresponding macros,
functions, and values for decimal floating types. Likewise, the "rounding direction mode" is
understood to refer to the rounding direction mode for decimal floating-point arithmetic.
5 Where a binding between the C language and IEC 60559 is indicated, the IEC 60559-specified
behavior is adopted by reference, unless stated otherwise.
F.2 [Types]
1 The C floating types match the IEC 60559 formats as follows:
— The float type matches the IEC 60559 binary32 format.
— The double type matches the IEC 60559 binary64 format.
— The long double type matches the IEC 60559 binary128 format, else an IEC 60559 binary64-
extended format, [436] else a non-IEC 60559 extended format, else the IEC 60559 binary64
format.
Any non-IEC 60559 extended format used for the long double type shall have more precision than
IEC 60559 binary64 and at least the range of IEC 60559 binary64.[437] The value of FLT_ROUNDS
applies to all IEC 60559 types supported by the implementation, but need not apply to non-IEC 60559
types.
Recommended practice
Footnote 436) IEC 60559 binary64-extended formats include the common 80-bit IEC 60559 format.
Footnote 437) A non-IEC 60559 long double type is required to provide infinity and NaNs, as its values include all double values.
2 The long double type should match the IEC 60559 binary128 format, else an IEC 60559 binary64-
extended format.
F.2.1 [Infinities and NaNs]
1 Since negative and positive infinity are representable in IEC 60559 formats, all real numbers lie
within the range of representable values (<IP_ADDRESS>.2).
2 The NAN and INFINITY macros in <float.h> and the nan functions in <math.h> provide designa-
tions for IEC 60559 quiet NaNs and infinities. The FLT_SNAN, DBL_SNAN, and LDBL_SNAN macros in
<float.h> provide designations for IEC 60559 signaling NaNs.
3 This annex does not require the full support for signaling NaNs specified in IEC 60559. This
annex uses the term NaN, unless explicitly qualified, to denote quiet NaNs. Where specification of
signaling NaNs is not provided, the behavior of signaling NaNs is implementation-defined (either
treated as an IEC 60559 quiet NaN or treated as an IEC 60559 signaling NaN). [438]
Footnote 438) Since NaNs created by IEC 60559 arithmetic operations are always quiet, quiet NaNs (along with infinities) are sufficient
for closure of the arithmetic.
4 Any operator or <math.h> function that raises an "invalid" floating-point exception, if delivering a
floating type result, shall return a quiet NaN, unless explicitly specified otherwise.
5 In order to support signaling NaNs as specified in IEC 60559, an implementation should adhere to
the following recommended practice.
Recommended practice
6 Any floating-point operator or <math.h> function or macro with a signaling NaN input, unless
explicitly specified otherwise, raises an "invalid" floating-point exception.
7 NOTE Some functions do not propagate quiet NaN arguments. For example, hypot(x, y) returns infinity if x or y is
infinite and the other is a quiet NaN. The recommended practice in this subclause specifies that such functions (and others)
raise the "invalid" floating-point exception if an argument is a signaling NaN, which also implies they return a quiet NaN in
these cases.
8 The <fenv.h> header defines the macro FE_SNANS_ALWAYS_SIGNAL if and only if the implemen-
tation follows the recommended practice in this subclause. If defined, FE_SNANS_ALWAYS_SIGNAL
expands to the integer constant 1.
F.3 [Operations]
1 C operators, functions, and function-like macros provide operations specified by IEC 60559 as shown
in the following table. In the table, C functions are represented by the function name without a type
suffix. Specifications for the C facilities are provided in the listed clauses. The C specifications are
intended to match IEC 60559, unless stated otherwise.
Operation binding
IEC 60559 operation C operation Clause
roundToIntegralTiesToEven roundeven <IP_ADDRESS>, F.10.6.8
roundToIntegralTiesAway round <IP_ADDRESS>, F.10.6.6
roundToIntegralTowardZero trunc <IP_ADDRESS>, F.10.6.9
roundToIntegralTowardPositive ceil <IP_ADDRESS>, F.10.6.1
roundToIntegralTowardNegative floor <IP_ADDRESS>, F.10.6.2
roundToIntegralExact rint <IP_ADDRESS>, F.10.6.4
nextUp nextup <IP_ADDRESS>, F.10.8.5
nextDown nextdown <IP_ADDRESS>, F.10.8.6
getPayload getpayload F.10.13.1
setPayload setpayload F.10.13.2
setPayloadSignaling setpayloadsig F.10.13.3
quantize quantize <IP_ADDRESS>
sameQuantum samequantum <IP_ADDRESS>
quantum quantum <IP_ADDRESS>
encodeDecimal encodedec <IP_ADDRESS>
decodeDecimal decodedec <IP_ADDRESS>
encodeBinary encodebin <IP_ADDRESS>
decodeBinary decodebin <IP_ADDRESS>
remainder remainder, remquo <IP_ADDRESS>, F.10.7.2,
<IP_ADDRESS>, F.10.7.3
maximum fmaximum <IP_ADDRESS>, F.10.9.4
minimum fminimum <IP_ADDRESS>, F.10.9.4
maximumMagnitude fmaximum_mag <IP_ADDRESS>, F.10.9.4
minimumMagnitude fminimum_mag <IP_ADDRESS>, F.10.9.4
maximumNumber fmaximum_num <IP_ADDRESS>, F.10.9.5
minimumNumber fminimum_num <IP_ADDRESS>, F.10.9.5
maximumMagnitudeNumber fmaximum_mag_num <IP_ADDRESS>, F.10.9.5
minimumMagnitudeNumber fminimum_mag_num <IP_ADDRESS>, F.10.9.5
scaleB scalbn, scalbln <IP_ADDRESS>, F.10.3.19
logB logb, ilogb, llogb <IP_ADDRESS>, F.10.3.17,
<IP_ADDRESS>, F.10.3.8,
<IP_ADDRESS>, F.10.3.10
addition + , fadd, faddl, daddl 6.5.6, <IP_ADDRESS>,
F.10.11
subtraction - , fsub, fsubl, dsubl 6.5.6, <IP_ADDRESS>,
F.10.11
multiplication * , fmul, fmull, dmull 6.5.5, <IP_ADDRESS>,
F.10.11
division / , fdiv, fdivl, ddivl 6.5.5, <IP_ADDRESS>,
F.10.11
squareRoot sqrt, fsqrt, fsqrtl, dsqrtl <IP_ADDRESS>, F.10.4.10,
<IP_ADDRESS>, F.10.11
fusedMultiplyAdd fma, ffma, ffmal, dfmal <IP_ADDRESS>, F.10.10.1,
<IP_ADDRESS>, F.10.11
convertFromInt cast and implicit conversion <IP_ADDRESS>, 6.5.4
convertToIntegerTiesToEven fromfp, ufromfp <IP_ADDRESS>, F.10.6.10
convertToIntegerTowardZero
convertToIntegerTowardPositive
convertToIntegerTowardNegative
convertToIntegerTiesToAway fromfp, ufromfp, lround, <IP_ADDRESS>, F.10.6.10,
llround <IP_ADDRESS>, F.10.6.7
convertToIntegerExactTiesToEven fromfpx, ufromfpx <IP_ADDRESS>, F.10.6.11
convertToIntegerExactTowardZero
convertToIntegerExactTowardPositive
convertToIntegerExactTowardNegative
convertToIntegerExactTiesToAway
convertFormat - different formats cast and implicit conversions <IP_ADDRESS>, 6.5.4
convertFormat - same format canonicalize <IP_ADDRESS>, F.10.8.7
convertFromDecimalCharacter strtod, wcstod, scanf, wscanf , <IP_ADDRESS>, <IP_ADDRESS>.2,
decimal floating constants <IP_ADDRESS>, <IP_ADDRESS>,
F.5
convertToDecimalCharacter printf, wprintf , strfromd <IP_ADDRESS>, <IP_ADDRESS>,
<IP_ADDRESS>, F.5
convertFromHexCharacter strtod, wcstod, scanf, wscanf , <IP_ADDRESS>, <IP_ADDRESS>.2,
hexadecimal floating constants <IP_ADDRESS>, <IP_ADDRESS>,
F.5
convertToHexCharacter printf, wprintf , strfromd <IP_ADDRESS>, <IP_ADDRESS>,
<IP_ADDRESS>, F.5
copy memcpy, memmove, +(x) <IP_ADDRESS>, <IP_ADDRESS>
negate -(x) <IP_ADDRESS>
abs fabs <IP_ADDRESS>, F.10.4.3
copySign copysign <IP_ADDRESS>, F.10.8.1
compareQuietEqual == 6.5.9, F.9.3
compareQuietNotEqual != 6.5.9, F.9.3
compareSignalingEqual iseqsig <IP_ADDRESS>, F.10.14.1
compareSignalingGreater > 6.5.8, F.9.3
compareSignalingGreaterEqual >= 6.5.8, F.9.3
compareSignalingLess < 6.5.8, F.9.3
compareSignalingLessEqual <= 6.5.8, F.9.3
compareSignalingNotEqual ! iseqsig(x) <IP_ADDRESS>, F.10.14.1
compareSignalingNotGreater ! (x > y) 6.5.8, F.9.3
compareSignalingLessUnordered ! (x >= y) 6.5.8, F.9.3
compareSignalingNotLess ! (x < y) 6.5.8, F.9.3
compareSignalingGreaterUnordered ! (x <= y) 6.5.8, F.9.3
compareQuietGreater isgreater <IP_ADDRESS>
compareQuietGreaterEqual isgreaterequal <IP_ADDRESS>
compareQuietLess isless <IP_ADDRESS>
compareQuietLessEqual islessequal <IP_ADDRESS>
compareQuietUnordered isunordered <IP_ADDRESS>
compareQuietNotGreater ! isgreater(x, y) <IP_ADDRESS>
compareQuietLessUnordered ! isgreaterequal(x, y) <IP_ADDRESS>
compareQuietNotLess ! isless(x, y) <IP_ADDRESS>
compareQuietGreaterUnordered ! islessequal(x, y) <IP_ADDRESS>
compareQuietOrdered ! isunordered(x, y) <IP_ADDRESS>
class fpclassify, signbit, <IP_ADDRESS>, <IP_ADDRESS>,
issignaling <IP_ADDRESS>
isSignMinus signbit <IP_ADDRESS>
isNormal isnormal <IP_ADDRESS>
isFinite isfinite <IP_ADDRESS>
isZero iszero <IP_ADDRESS>
isSubnormal issubnormal <IP_ADDRESS>
isInfinite isinf <IP_ADDRESS>
isNaN isnan <IP_ADDRESS>
isSignaling issignaling <IP_ADDRESS>
isCanonical iscanonical <IP_ADDRESS>
radix FLT_RADIX <IP_ADDRESS>.2
totalOrder totalorder F.10.12.1
totalOrderMag totalordermag F.10.12.2
lowerFlags feclearexcept <IP_ADDRESS>
raiseFlags fesetexcept <IP_ADDRESS>
testFlags fetestexcept <IP_ADDRESS>
testSavedFlags fetestexceptflag <IP_ADDRESS>
restoreFlags fesetexceptflag <IP_ADDRESS>
saveAllFlags fegetexceptflag <IP_ADDRESS>
getBinaryRoundingDirection fegetround <IP_ADDRESS>
setBinaryRoundingDirection fesetround <IP_ADDRESS>
saveModes fegetmode <IP_ADDRESS>
restoreModes fesetmode <IP_ADDRESS>
defaultModes fesetmode(FE_DFL_MODE) <IP_ADDRESS>, 7.6
2 The IEC 60559 requirement that certain of its operations be provided for operands of different
formats (of the same radix) is satisfied by C’s usual arithmetic conversions (<IP_ADDRESS>) and function-call
argument conversions (<IP_ADDRESS>). For example, the following operations take float f and double d
inputs and produce a long double result:
(long double)f * d
powl(f, d)
3 The functions fmin and fmax have been superseded by fminimum_num and fmaximum_num. The fmin
and fmax functions provide the minNum and maxNum operations specified in (the superseded)
IEC 60559:2011.
4 Whether C assignment (6.5.16) (and conversion as if by assignment) to the same format is an
IEC 60559 convertFormat or copy operation[439] is implementation-defined, even if <fenv.h> defines
the macro FE_SNANS_ALWAYS_SIGNAL (F.2.1). If the return expression of a return statement is
evaluated to the floating-point format of the return type, it is implementation-defined whether a
convertFormat operation is applied to the result of the return expression.
Footnote 439) Where the source and destination formats are the same, convertFormat operations differ from copy operations in
that convertFormat operations raise the "invalid" floating-point exception on signaling NaN inputs and do not propagate
non-canonical encodings.
5 The unary + and - operators raises no floating-point exceptions, even if the operand is a signaling
NaN.
6 The C classification macros fpclassify, iscanonical, isfinite, isinf, isnan, isnormal,
issignaling, issubnormal, iszero, and signbit provide the IEC 60559 operations indicated
in the table above provided their arguments are in the format of their semantic type. Then these
macros raise no floating-point exceptions, even if an argument is a signaling NaN.
7 The signbit macro, providing the IEC 60559 isSignMinus operation, determines the sign of its
argument value as the sign bit of the value’s representation. This applies to all values, including
NaNs whose sign bit is not generally interpreted by IEC 60559.
8 The C nearbyint functions (<IP_ADDRESS>, F.10.6.3) provide the nearbyinteger function recommended in
the Appendix to (superseded) ANSI/IEEE 854.
9 The C nextafter (<IP_ADDRESS>, F.10.8.3) and nexttoward (<IP_ADDRESS>, F.10.8.4) functions provide the
nextafter function recommended in the Appendix to (superseded) IEC 60559:1989 (but with a
minor change to better handle signed zeros).
10 The macros (7.6) FE_DOWNWARD, FE_TONEAREST, FE_TONEARESTFROMZERO, FE_TOWARDZERO, and
FE_UPWARD, which are used in conjunction with the fegetround and fesetround functions and the
FENV_ROUND pragma, represent the IEC 60559 rounding-direction attributes roundTowardNegative,
roundTiesToEven, roundTiesToAway, roundTowardZero, and roundTowardPositive, respectively,
for binary floating-point arithmetic. Support for the roundTiesToAway attribute for binary floating-
point arithmetic, and hence for the FE_TONEARESTFROMZERO macro, is optional.
11 The C fegetenv (<IP_ADDRESS>), feholdexcept (<IP_ADDRESS>), fesetenv (<IP_ADDRESS>) and feupdateenv (<IP_ADDRESS>)
functions provide a facility to manage the dynamic floating-point environment, comprising the
IEC 60559 status flags and dynamic control modes.
12 IEC 60559 requires operations with specified operand and result formats. Therefore, math functions
that are bound to IEC 60559 operations (see table above) must remove any extra range and precision
from arguments or results.
13 IEC 60559 requires operations that round their result to formats the same as and wider than the
operands, in addition to the operations that round their result to narrower formats (see 7.12.14).
Operators (+ , - , * , and / ) whose evaluation formats are wider than the semantic type (<IP_ADDRESS>.2)
might not support some of the IEEE 60559 operations, because getting a result in a given format
might require a cast that could introduce an extra rounding error. The functions that round result to
narrower type (7.12.14) provide the IEC 60559 operations that round result to same and wider (as
well as narrower) formats, in those cases where built-in operators and casts do not. For example,
ddivl(x, y) computes a correctly rounded double divide of float x by float y, regardless of
the evaluation method.
14 Decimal versions of the remquo library function are not provided. (The decimal remainder functions
provide the remainder operation defined by IEC 60559.)
15 The binding for the convertFormat operation applies to all conversions among IEC 60559 formats.
Therefore, for implementations that conform to Annex F, conversions between decimal floating types
and standard floating types with IEC 60559 formats are correctly rounded and raise floating-point
exceptions as specified in IEC 60559.
16 IEC 60559 specifies the convertFromHexCharacter and convertToHexCharacter operations only for
binary floating-point arithmetic.
17 The integer constant 10 provides the radix operation defined in IEC 60559 for decimal floating-point
arithmetic.
18 The fe_dec_getround (<IP_ADDRESS>) and fe_dec_setround (<IP_ADDRESS>) functions provide the getDeci-
malRoundingDirection and setDecimalRoundingDirection operations defined in IEC 60559 for
decimal floating-point arithmetic. The macros (7.6) FE_DEC_DOWNWARD, FE_DEC_TONEAREST,
FE_DEC_TONEARESTFROMZERO, FE_DEC_TOWARDZERO, and FE_DEC_UPWARD, which are used in con-
junction with the fe_dec_getround and fe_dec_setround functions and the FENV_DEC_ROUND
pragma, represent the IEC 60559 rounding-direction attributes roundTowardNegative, roundTiesTo-
Even, roundTiesToAway, roundTowardZero, and roundTowardPositive, respectively, for decimal
floating-point arithmetic.
19 The llquantexpdN (<IP_ADDRESS>) functions compute the (quantum) exponent q defined in IEC 60559
for decimal numbers viewed as having integer significands.
20 The C functions in the following table correspond to mathematical operations recommended by
IEC 60559. However, correct rounding, which IEC 60559 specifies for its operations, is not required
for the C functions in the table. 7.33.8 (potentially) reserves cr_ prefixed names for functions fully
matching the IEC 60559 mathematical operations. In the table, the C functions are represented by
the function name without a type suffix.

IEC 60559 operation C function Clause
cos cos <IP_ADDRESS>, F.10.1.5
tan tan <IP_ADDRESS>, F.10.1.7
sinPi sinpi <IP_ADDRESS>, F.10.1.13
cosPi cospi <IP_ADDRESS>, F.10.1.12
tanPi tanpi <IP_ADDRESS>, F.10.1.14
asinPi asinpi <IP_ADDRESS>, F.10.1.9
acosPi acospi <IP_ADDRESS>, F.10.1.8
atanPi atanpi <IP_ADDRESS>, F.10.1.10
atan2Pi atan2pi <IP_ADDRESS>, F.10.1.11
asin asin <IP_ADDRESS>, F.10.1.2
acos acos <IP_ADDRESS>, F.10.1.1
atan atan <IP_ADDRESS>, F.10.1.3
atan2 atan2 <IP_ADDRESS>, F.10.1.4
sinh sinh <IP_ADDRESS>, F.10.2.5
cosh cosh <IP_ADDRESS>, F.10.2.4
tanh tanh <IP_ADDRESS>, F.10.2.6
asinh asinh <IP_ADDRESS>, F.10.2.2
acosh acosh <IP_ADDRESS>, F.10.2.1
atanh atanh <IP_ADDRESS>, F.10.2.3
F.4 [Floating to integer conversion]
1 If the integer type is bool, <IP_ADDRESS> applies and the conversion raises no floating-point exceptions if
the floating-point value is not a signaling NaN. Otherwise, if the floating value is infinite or NaN
or if the integral part of the floating value exceeds the range of the integer type, then the "invalid"
floating-point exception is raised and the resulting value is unspecified. Otherwise, the resulting
value is determined by <IP_ADDRESS>. Conversion of an integral floating value that does not exceed the
range of the integer type raises no floating-point exceptions; whether conversion of a non-integral
floating value raises the "inexact" floating-point exception is unspecified.[440]
Footnote 440) IEC 60559 recommends that implicit floating-to-integer conversions raise the "inexact" floating-point exception for
non-integer in-range values. In those cases where it matters, library functions can be used to effect such conversions with or
without raising the "inexact" floating- point exception. See fromfp, ufromfp, fromfpx, ufromfpx, rint, lrint, llrint, and
nearbyint in <math.h>.
F.5 [Conversions between binary floating types and decimal character se-]
1 quences
The <float.h> header defines the macro
CR_DECIMAL_DIG
which expands to an integer constant expression suitable for use in #if preprocessing directives
whose value is a number such that conversions between all supported IEC 60559 binary formats and
character sequences with at most CR_DECIMAL_DIG significant decimal digits are correctly rounded.
The value of CR_DECIMAL_DIG shall be at least M + 3, where M is the maximum value of the
T_DECIMAL_DIG macros for IEC 60559 binary formats. If the implementation correctly rounds for
all numbers of significant decimal digits, then CR_DECIMAL_DIG shall have the value of the macro
UINTMAX_MAX.
2 Conversions of types with IEC 60559 binary formats to character sequences with more than
CR_DECIMAL_DIG significant decimal digits shall correctly round to CR_DECIMAL_DIG significant
digits and pad zeros on the right.
3 Conversions from character sequences with more than CR_DECIMAL_DIG significant decimal digits
to types with IEC 60559 binary formats shall correctly round to an intermediate character sequence
with CR_DECIMAL_DIG significant decimal digits, according to the applicable rounding direction,
and correctly round the intermediate result (having CR_DECIMAL_DIG significant decimal digits) to
the destination type. The "inexact" floating-point exception is raised (once) if either conversion
is inexact.[441] (The second conversion may raise the "overflow" or "underflow" floating-point
exception.)
Footnote 441) The intermediate conversion is exact only if all input digits after the first CR_DECIMAL_DIG digits are 0.
4 The specification in this subclause assures conversion between IEC 60559 binary format and decimal
character sequence follows all pertinent recommended practice. It also assures conversion from
IEC 60559 format to decimal character sequence with at least T_DECIMAL_DIG digits and back, using
to-nearest rounding, is the identity function, where T is the macro prefix for the format.
5 Functions such as strtod that convert character sequences to floating types honor the rounding
direction. Hence, if the rounding direction might be upward or downward, the implementation
cannot convert a minus-signed sequence by negating the converted unsigned sequence.
6 NOTE IEC 60559 specifies that conversion to one-digit character strings using roundTiesToEven when both choices have
an odd least significant digit, shall produce the value with the larger magnitude. For example, this can happen with 9.5e2
whose nearest neighbors are 9.e2 and 1.e3, both of which have a single odd digit in the significand part.
F.6 [The return statement]
If the return expression is evaluated in a floating-point format different from the return type, the
expression is converted as if by assignment[442] to the return type of the function and the resulting
value is returned to the caller.
Footnote 442) Assignment removes any extra range and precision.

Recommended practice
2 A contracted expression should raise floating-point exceptions in a manner generally consistent
with the basic arithmetic operations.
F.8 [Floating-point environment]
1 The floating-point environment defined in <fenv.h> includes the IEC 60559 floating-point exception
status flags and rounding-direction control modes. It may also include other floating-point status or
modes that the implementation provides as extensions.[443]
Footnote 443) Dynamic rounding precision and trap enablement modes are examples of such extensions.
2 This annex does not include support for IEC 60559’s optional alternate exception handling. The
specification in this annex assumes IEC 60559 default exception handling: the flag is set, a default
result is delivered, and execution continues. Implementations might provide alternate exception
handling as an extension.
F.8.1 [Environment management]
1 IEC 60559 requires that floating-point operations implicitly raise floating-point exception status
flags, and that rounding control modes can be set explicitly to affect result values of floating-point
operations. These changes to the floating-point state are treated as side effects which respect
sequence points.[444]
Footnote 444) If the state for the FENV_ACCESS pragma is "off", the implementation is free to assume the dynamic floating-point control
modes will be the default ones and the floating-point status flags will not be tested, which allows certain optimizations
(see F.9).
F.8.2 [Translation]
1 During translation, constant rounding direction modes (7.6.2) are in effect where specified. Else-
where, during translation the IEC 60559 default modes are in effect:
— The rounding direction mode is rounding to nearest.
— The rounding precision mode (if supported) is set so that results are not shortened.
— Trapping or stopping (if supported) is disabled on all floating-point exceptions.
Recommended practice
2 The implementation should produce a diagnostic message for each translation-time floating-point
exception, other than "inexact";[445] the implementation should then proceed with the translation of
the program.
Footnote 445) As floating constants are converted to appropriate internal representations at translation time, their conversion is subject
to constant or default rounding modes and raises no execution-time floating-point exceptions (even where the state of the
FENV_ACCESS pragma is "on"). Library functions, for example strtod, provide execution-time conversion of numeric strings.
F.8.3 [Execution]
1 At program startup the dynamic floating-point environment is initialized as prescribed by IEC 60559:
— All floating-point exception status flags are cleared.
— The dynamic rounding direction mode is rounding to nearest.
— The dynamic rounding precision mode (if supported) is set so that results are not shortened.
— Trapping or stopping (if supported) is disabled on all floating-point exceptions.
F.8.4 [Constant expressions]
1 An arithmetic constant expression of floating type, other than one in an initializer for an object that
has static or thread storage duration, is evaluated (as if) during execution; thus, it is affected by any
operative floating-point control modes and raises floating-point exceptions as required by IEC 60559
(provided the state for the FENV_ACCESS pragma is "on").[446]
Footnote 446) Where the state for the FENV_ACCESS pragma is "on", results of inexact expressions like 1.0/3.0 are affected by rounding
modes set at execution time, and expressions such as 0.0/0.0 and 1.0/0.0 generate execution-time floating-point exceptions.
The programmer can achieve the efficiency of translation-time evaluation through static initialization, such as
const static double one_third = 1.0/3.0;
2 EXAMPLE
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
void f(void)
{
float w[] = { 0.0/0.0 }; // raises an exception
static float x = 0.0/0.0; // does not raise an exception
float y = 0.0/0.0; // raises an exception
double z = 0.0/0.0; // raises an exception
/* ... */
}
3 For the static initialization, the division is done at translation time, raising no (execution-time) floating-point exceptions. On
the other hand, for the three automatic initializations the invalid division occurs at execution time.
F.8.5 [Initialization]
1 All computation for automatic initialization is done (as if) at execution time; thus, it is affected by
any operative modes and raises floating-point exceptions as required by IEC 60559 (provided the
state for the FENV_ACCESS pragma is "on"). All computation for initialization of objects that have
static or thread storage duration is done (as if) at translation time.
2 EXAMPLE
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
void f(void)
{
float u[] = { 1.1e75 }; // raises exceptions
static float v = 1.1e75; // does not raise exceptions
float w = 1.1e75; // raises exceptions
double x = 1.1e75; // may raise exceptions
float y = 1.1e75f; // may raise exceptions
long double z = 1.1e75; // does not raise exceptions
/* ... */
}
3 The static initialization of v raises no (execution-time) floating-point exceptions because its computation is done at translation
time. The automatic initialization of u and w require an execution-time conversion to float of the wider value 1.1e75,
which raises floating-point exceptions. The automatic initializations of x and y entail execution-time conversion; however, in
some expression evaluation methods, the conversions is not to a narrower format, in which case no floating-point exception
is raised.[447] The automatic initialization of z entails execution-time conversion, but not to a narrower format, so no
floating-point exception is raised. Note that the conversions of the floating constants 1.1e75 and 1.1e75f to their internal
representations occur at translation time in all cases.
Footnote 447) Use of float_t and double_t variables increases the likelihood of translation-time computation. For example, the
automatic initialization
double_t x = 1.1e75;
could be done at translation time, regardless of the expression evaluation method.
F.8.6 [Changing the environment]
1 Operations defined in 6.5 and functions and macros defined for the standard libraries change
floating-point status flags and control modes just as indicated by their specifications (including
conformance to IEC 60559). They do not change flags or modes (so as to be detectable by the user) in
any other cases.
2 If the floating-point exceptions represented by the argument to the feraiseexcept function in
<fenv.h> include both "overflow" and "inexect", then "overflow" is raised before "inexact". Simi-
larly, if the represented exceptions include both "underflow" and "inexact", then "underflow" is
raised before "inexact".
F.9 [Optimization]
1 This section identifies code transformations that might subvert IEC 60559-specified behavior, and
others that do not.
F.9.1 [Global transformations]
1 Floating-point arithmetic operations and external function calls may entail side effects which
optimization shall honor, at least where the state of the FENV_ACCESS pragma is "on". The flags
and modes in the floating-point environment may be regarded as global variables; floating-point
operations (+ , * , etc.) implicitly read the modes and write the flags.
2 Concern about side effects may inhibit code motion and removal of seemingly useless code. For
example, in
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
void f(double x)
{
/* ... */
for (i = 0; i < n; i++) x + 1;
/* ... */
}
x+1 might raise floating-point exceptions, so cannot be removed. And since the loop body might not
execute (maybe 0 ≥ n), x+1 cannot be moved out of the loop. (Of course these optimizations are
valid if the implementation can rule out the nettlesome cases.)
3 This specification does not require support for trap handlers that maintain information about
the order or count of floating-point exceptions. Therefore, between function calls, floating-point
exceptions need not be precise: the actual order and number of occurrences of floating-point
exceptions (> 1) may vary from what the source code expresses. Thus, the preceding loop could be
treated as
if (0 < n) x + 1;
F.9.2 [Expression transformations]
1 Valid expression transformations must preserve numerical values.
2 The equivalences noted below apply to expressions of standard floating types.
x/2 ↔ x × 0.5 Although similar transformations involving inexact constants generally do not
yield equivalent expressions, if the constants are exact then such transforma-
tions can be made on IEC 60559 machines and others that round perfectly.
1 × x and x/1 → x The expressions 1 × x, x/1, and x may be regarded as equivalent (on IEC 60559
machines, among others).[448]
x/x → 1.0 The expressions x/x and 1.0 are not equivalent if x can be zero, infinite, or NaN.
x − y ↔ x + (−y) The expressions x − y, x + (−y), and (−y) + x are equivalent (on IEC 60559
machines, among others).
x − y ↔ −(y − x) The expressions x − y and −(y − x) are not equivalent because 1 − 1 is +0 but
−(1 − 1) is −0 (in the default rounding direction).[449]
x − x → 0.0 The expressions x − x and 0.0 are not equivalent if x is a NaN or infinite.
0 × x → 0.0 The expressions 0 × x and 0.0 are not equivalent if x is a NaN, infinite, or −0.
x+0→x The expressions x + 0 and x are not equivalent if x is −0, because (−0) + (+0)
yields +0 (in the default rounding direction), not −0.
x−0→x (+0) − (+0) yields −0 when rounding is downward (toward −∞), but +0
otherwise, and (−0)−(+0) always yields −0; so, if the state of the FENV_ACCESS
pragma is "off", promising default rounding, then the implementation can
replace x − 0 by x, even if x might be zero.
−x ↔ 0 − x The expressions −x and 0−x are not equivalent if x is +0, because −(+0) yields
−0, but 0 − (+0) yields +0 (unless rounding is downward).
Footnote 448) Implementations might have non-required features that invalidate these and other transformations that remove arithmetic
operators. Examples include strict support for signaling NaNs (an optional feature) and alternate exception handling (not
included in this specification).
Footnote 449) IEC 60559 prescribes a signed zero to preserve mathematical identities across certain discontinuities. Examples include:
1/(1/±∞) is ±∞
and
conj(csqrt(z)) is csqrt(conj(z)),
for complex z.
3 For expressions of decimal floating types, transformations must preserve quantum exponents, as
well as numerical values (<IP_ADDRESS>.3).
4 EXAMPLE 1. × x → x is valid for decimal floating-point expressions x, but 1.0 × x → x is not:
1. × 12.34 = (+1, 1, 0) × (+1, 1234, −2) yields (+1, 1234, −2) = 12.34
1.0 × 12.34 = (+1, 10, −1) × (+1, 1234, −2) yields (+1, 12340, −3) = 12.340
In the second case, the factor 12.34 and the result 12.340 have different quantum exponents, demonstrating that 1.0 × x and
x are not equivalent expressions.
F.9.3 [Relational operators]
1 x ̸= x → false The expression x ̸= x is true if x is a NaN.
x = x → true The expression x = x is false if x is a NaN.
x < y → isless(x, y) (and similarly for ≤, >, ≥) Though equal, these expressions are not equiv-
alent because of side effects when x or y is a NaN and the state of the
FENV_ACCESS pragma is "on". This transformation, which would be de-
sirable if extra code were required to cause the "invalid" floating-point
exception for unordered cases, could be performed provided the state of the
FENV_ACCESS pragma is "off".
The sense of relational operators shall be maintained. This includes handling unordered cases as
expressed by the source code.
2 EXAMPLE
// calls g and raises "invalid" if a and b are unordered
if (a < b)
f();
else
g();
is not equivalent to
// calls f and raises "invalid" if a and b are unordered
if (a >= b)
g();
else
f();
nor to
// calls f without raising "invalid" if a and b are unordered
if (isgreaterequal(a,b))
g();
else
f();
nor, unless the state of the FENV_ACCESS pragma is "off", to
// calls g without raising "invalid" if a and b are unordered
if (isless(a,b))
f();
else
g();
but is equivalent to
if (!(a < b))
g();
else
f();
F.9.4 [Constant arithmetic]
1 The implementation shall honor floating-point exceptions raised by execution-time constant arith-
metic wherever the state of the FENV_ACCESS pragma is "on". (See F.8.4 and F.8.5.) An operation
on constants that raises no floating-point exception can be folded during translation, except, if the
state of the FENV_ACCESS pragma is "on", a further check is required to assure that changing the
rounding direction to downward does not alter the sign of the result,[450] and implementations that
support dynamic rounding precision modes shall assure further that the result of the operation
raises no floating-point exception when converted to the semantic type of the operation.
Footnote 450) 0-0 yields-0 instead of +0 just when the rounding direction is downward.
F.10 [Mathematics <math.h> and <tgmath.h>]
1 This subclause contains specifications of <math.h> and <tgmath.h> facilities that are particularly
suited for IEC 60559 implementations.
2 The Standard C macro HUGE_VAL and its float and long double analogs, HUGE_VALF and
HUGE_VALL, expand to expressions whose values are positive infinities.
3 For each single-argument function f in <math.h> whose mathematical counterpart is symmetric
(even), f(-x) is f(x) for all rounding modes and for all x in the (valid) domain of the function. For
each single-argument function f in <math.h> whose mathematical counterpart is antisymmetric
(odd), f(-x) is-f(x) for the IEC 60559 rounding modes roundTiesToEven, roundTiesToAway, and
roundTowardZero, and for all x in the (valid) domain of the function. The atan2 and atan2pi
functions are odd in their first argument.
4 Special cases for functions in <math.h> are covered directly or indirectly by IEC 60559. The functions
that IEC 60559 specifies directly are identified in F.3. The other functions in <math.h> treat infinities,
NaNs, signed zeros, subnormals, and (provided the state of the FENV_ACCESS pragma is "on") the
floating-point status flags in a manner consistent with IEC 60559 operations.
5 The expression math_errhandling & MATH_ERREXCEPT shall evaluate to a nonzero value.
6 The functions bound to operations in IEC 60559 (F.3) are fully specified by IEC 60559, including
rounding behaviors and floating-point exceptions.
7 The "invalid" and "divide-by-zero" floating-point exceptions are raised as specified in subsequent
subclauses of this annex.
8 The "overflow" floating-point exception is raised whenever an infinity — or, because of rounding di-
rection, a maximal-magnitude finite number — is returned in lieu of a finite value whose magnitude
is too large.
9 The "underflow" floating-point exception is raised whenever a computed result is tiny[451] and the
returned result is inexact.
Footnote 451) Tiny generally indicates having a magnitude in the subnormal range. See IEC 60559 for details about detecting tininess.
10 Whether or when library functions not listed in the "Operation binding" table in F.3 raise the
"inexact" floating-point exception is unspecified, unless stated otherwise.
11 Whether or when library functions not listed in the "Operation binding" table in F.3 raise a spurious
"underflow" floating-point exception is not specified by this annex.[452]
Footnote 452) It is intended that spurious "underflow" and "inexact" floating-point exceptions are raised only if avoiding them would
be too costly. 7.12.1 specifies that if math_errhandling & MATH_ERREXCEPT is nonzero, then an "underflow" floating-point
exception shall not be raised unless an underflow range error occurs.
12 As implied by F.8.6, library functions do not raise spurious "invalid", "overflow", or "divide-by-zero"
floating-point exceptions (detectable by the user).
13 Whether the functions not listed in the "Operation binding" table in F.3 honor the rounding direction
mode is implementation-defined, unless explicitly specified otherwise.
14 Functions with a NaN argument return a NaN result and raise no floating-point exception, except
where explicitly stated otherwise.
15 The specifications in the following subclauses append to the definitions in <math.h>. 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.
Recommended practice
16 IEC 60559 specifies correct rounding for the operations in the F.3 table of operations recommended
by IEC 60559, and thereby preserves useful mathematical properties such as symmetry, monotonicity,
and periodicity. The corresponding functions with (potentially) reserved cr_-prefixed names (7.33.8)
do the same. The C functions in the table, however, are not required to be correctly rounded, but
implementations should still preserve as many of these useful mathematical properties as possible.
17 If a function with one or more NaN arguments returns a NaN result, the result should be the same
as one of the NaN arguments (after possible type conversion), except perhaps for the sign.
F.10.1 [Trigonometric functions]
F.10.1.1 [The acos functions]
1 — acos(1) returns +0.
— acos(x) returns a NaN and raises the "invalid" floating-point exception for |x| > 1.
F.10.1.2 [The asin functions]
1 — asin(±0) returns ±0.
— asin(x) returns a NaN and raises the "invalid" floating-point exception for |x| > 1.
F.10.1.3 [The atan functions]
1 — atan(±0) returns ±0.
— atan(±∞) returns ± π2 .
F.10.1.4 [The atan2 functions]
1 — atan2(±0, −0) returns ±π.[453]
— atan2(±0, +0) returns ±0.
— atan2(±0, x) returns ±π for x < 0.
— atan2(±0, x) returns ±0 for x > 0.
— atan2(y, ±0) returns − π2 for y < 0.
— atan2(y, ±0) returns π2 for y > 0.
— atan2(±y, −∞) returns ±π for finite y > 0.
— atan2(±y, +∞) returns ±0 for finite y > 0.
— atan2(±∞, x) returns ± π2 for finite x.
— atan2(±∞, −∞) returns ± 3π
4 .
— atan2(±∞, +∞) returns ± π4 .
Footnote 453) atan2(0, 0) does not raise the "invalid" floating-point exception, nor does atan2(y, 0) raise the "divide-by-zero" floating-
point exception.
F.10.1.5 [The cos functions]
1 — cos(±0) returns 1.
— cos(±∞) returns a NaN and raises the "invalid" floating-point exception.
F.10.1.6 [The sin functions]
1 — sin(±0) returns ±0.
— sin(±∞) returns a NaN and raises the "invalid" floating-point exception.
F.10.1.7 [The tan functions]
1 — tan(±0) returns ±0.
— tan(±∞) returns a NaN and raises the "invalid" floating-point exception.
F.10.1.8 [The acospi functions]
1 — acospi(+1) returns +0.
— acospi(x) returns a NaN and raises the "invalid" floating-point exception for |x| > 1.
F.10.1.9 [The asinpi functions]
1 — asinpi(±0) returns ±0.
— asinpi(x) returns a NaN and raises the "invalid" floating-point exception for |x| > 1.
F.10.1.10 [The atanpi functions]
1 — atanpi(±0) returns ±0.
— atanpi(±∞) returns ± 21 .
F.10.1.11 [The atan2pi functions]
1 — atan2pi(±0, −0) returns ±1.[454]
— atan2pi(±0, +0) returns ±0.
— atan2pi(±0, x) returns ±1 for x < 0.
— atan2pi(±0, x) returns ±0 for x > 0.
— atan2pi(y, ±0) returns − 12 for y < 0.
— atan2pi(y, ±0) returns + 12 for y > 0.
— atan2pi(±y, −∞) returns ±1 for finite y > 0.
— atan2pi(±y, +∞) returns ±0 for finite y > 0.
— atan2pi(±∞, x) returns ± 12 for finite x.
— atan2pi(±∞, −∞) returns ± 43 .
— atan2pi(±∞, +∞) returns ± 14 .
Footnote 454) atan2pi(0, 0) does not raise the "invalid" floating-point exception, nor does atan2pi(y, 0) raise the "divide-by-zero"
floating-point exception.
F.10.1.12 [The cospi functions]
1 — cospi(±0) returns 1.
— cospi(n + 12 ) returns +0, for integers n.
— cospi(±∞) returns a NaN and raises the "invalid" floating-point exception.
F.10.1.13 [The sinpi functions]
1 — sinpi(±0) returns ±0.
— sinpi(±n) returns ±0, for positive integers n.
— sinpi(±∞) returns a NaN and raises the "invalid" floating-point exception.
F.10.1.14 [The tanpi functions]
1 — tanpi(±0) returns ±0.
— tanpi(n) returns +0, for positive even and negative odd integers n.
— tanpi(n) returns −0, for positive odd and negative even integers n.
— tanpi(n + 12 ) returns +∞ and raises the "divide-by-zero" floating-point exception, for even
integers n.
— tanpi(n + 12 ) returns −∞ and raises the "divide-by-zero" floating-point exception, for odd
integers n.
— tanpi(±∞) returns a NaN and raises the "invalid" floating-point exception.
F.10.2 [Hyperbolic functions]
F.10.2.1 [The acosh functions]
1 — acosh(1) returns +0.
— acosh(x) returns a NaN and raises the "invalid" floating-point exception for x < 1.
— acosh(+∞) returns +∞.
F.10.2.2 [The asinh functions]
1 — asinh(±0) returns ±0.
— asinh(±∞) returns ±∞.
F.10.2.3 [The atanh functions]
1 — atanh(±0) returns ±0.
— atanh(±1) returns ±∞ and raises the "divide-by-zero" floating-point exception.
— atanh(x) returns a NaN and raises the "invalid" floating-point exception for |x| > 1.
F.10.2.4 [The cosh functions]
1 — cosh(±0) returns 1.
— cosh(±∞) returns +∞.
F.10.2.5 [The sinh functions]
1 — sinh(±0) returns ±0.
— sinh(±∞) returns ±∞.
F.10.2.6 [The tanh functions]
1 — tanh(±0) returns ±0.
— tanh(±∞) returns ±1.
F.10.3 [Exponential and logarithmic functions]
F.10.3.1 [The exp functions]
1 — exp(±0) returns 1.
— exp(−∞) returns +0.
— exp(+∞) returns +∞.
F.10.3.2 [The exp10 functions]
1 — exp10(±0) returns 1.
— exp10(−∞) returns +0.
— exp10(+∞) returns +∞.
F.10.3.3 [The exp10m1 functions]
1 — exp10m1(±0) returns ±0.
— exp10m1(−∞) returns −1.
— exp10m1(+∞) returns +∞.
F.10.3.4 [The exp2 functions]
1 — exp2(±0) returns 1.
— exp2(−∞) returns +0.
— exp2(+∞) returns +∞.
F.10.3.5 [The exp2m1 functions]
1 — exp2m1(±0) returns ±0.
— exp2m1(−∞) returns −1.
— exp2m1(+∞) returns +∞.
F.10.3.6 [The expm1 functions]
1 — expm1(±0) returns ±0.
— expm1(−∞) returns −1.
— expm1(+∞) returns +∞.
F.10.3.7 [The frexp functions]
1 — frexp(±0, exp) returns ±0, and stores 0 in the object pointed to by exp.
— frexp(±∞, exp) returns ±∞, and stores an unspecified value in the object pointed to by exp.
— frexp(NaN, exp) stores an unspecified value in the object pointed to by exp (and returns a
NaN).
2 frexp raises no floating-point exceptions if value is not a signaling NaN.
3 The returned value is independent of the current rounding direction mode.
4 On a binary system, the body of the frexp function might be
{
*exp = (value == 0) ? 0: (int)(1 + logb(value));
return scalbn(value, -(*exp));
}
F.10.3.8 [The ilogb functions]
1 When the correct result is representable in the range of the return type, the returned value is exact
and is independent of the current rounding direction mode.
2 If the correct result is outside the range of the return type, the numeric result is unspecified and the
"invalid" floating-point exception is raised.
3 ilogb(x), for x zero, infinite, or NaN, raises the "invalid" floating-point exception and returns the
value specified in <IP_ADDRESS>.
F.10.3.9 [The ldexp functions]
1 On a binary system, ldexp(x, exp) is equivalent to scalbn(x, exp).
F.10.3.10 [The llogb functions]
1 The llogb functions are equivalent to the ilogb functions, except that the llogb functions determine
a result in the long int type.
F.10.3.11 [The log functions]
1 — log(±0) returns −∞ and raises the "divide-by-zero" floating-point exception.
— log(1) returns +0.
— log(x) returns a NaN and raises the "invalid" floating-point exception for x < 0.
— log(+∞) returns +∞.
F.10.3.12 [The log10 functions]
1 — log10(±0) returns −∞ and raises the "divide-by-zero" floating-point exception.
— log10(1) returns +0.
— log10(x) returns a NaN and raises the "invalid" floating-point exception for x < 0.
— log10(+∞) returns +∞.
F.10.3.13 [The log10p1 functions]
1 — log10p1(±0) returns ±0.
— log10p1(−1) returns −∞ and raises the "divide-by-zero" floating-point exception.
— log10p1(x) returns a NaN and raises the "invalid" floating-point exception for x < −1.
— log10p1(+∞) returns +∞.
F.10.3.14 [The log1p and logp1 functions]
1 — logp1(±0) returns ±0.
— logp1(−1) returns −∞ and raises the "divide-by-zero" floating-point exception.
— logp1(x) returns a NaN and raises the "invalid" floating-point exception for x < −1.
— logp1(+∞) returns +∞.
The log1p functions are equivalent to the logp1 functions.
F.10.3.15 [The log2 functions]
1 — log2(±0) returns −∞ and raises the "divide-by-zero" floating-point exception.
— log2(1) returns +0.
— log2(x) returns a NaN and raises the "invalid" floating-point exception for x < 0.
— log2(+∞) returns +∞.
F.10.3.16 [The log2p1 functions]
1 — log2p1(±0) returns ±0.
— log2p1(−1) returns −∞ and raises the "divide-by-zero" floating-point exception.
— log2p1(x) returns a NaN and raises the "invalid" floating-point exception for x < −1.
— log2p1(+∞) returns +∞.
F.10.3.17 [The logb functions]
1 — logb(±0) returns −∞ and raises the "divide-by-zero" floating-point exception.
— logb(±∞) returns +∞.
2 The returned value is exact and is independent of the current rounding direction mode.
F.10.3.18 [The modf functions]
1 — modf(±x, iptr) returns a result with the same sign as x.
— modf(±∞, iptr) returns ±0 and stores ±∞ in the object pointed to by iptr.
— modf(NaN, iptr) stores a NaN in the object pointed to by iptr (and returns a NaN).
2 The returned values are exact and are independent of the current rounding direction mode.
3 modf behaves as though implemented by
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
double modf(double value, double *iptr)
{
int save_round = fegetround();
fesetround(FE_TOWARDZERO);
*iptr = nearbyint(value);
fesetround(save_round);
return copysign(
isinf(value) ? 0.0:
value - (*iptr), value);
}
F.10.3.19 [The scalbn and scalbln functions]
1 — scalbn(±0, n) returns ±0.
— scalbn(x, 0) returns x.
— scalbn(±∞, n) returns ±∞.
2 If the calculation does not overflow or underflow, the returned value is exact and independent of
the current rounding direction mode.
F.10.4 [Power and absolute value functions]
F.10.4.1 [The cbrt functions]
1 — cbrt(±0) returns ±0.
— cbrt(±∞) returns ±∞.
F.10.4.2 [The compoundn functions]
1 — compoundn(x, 0) returns 1 for x ≥ −1 or x a NaN.
— compoundn(x, n) returns a NaN and raises the "invalid" floating-point exception for x < −1.
— compoundn(−1, n) returns +∞ and raises the divide-by-zero floating-point exception for n < 0.
— compoundn(−1, n) returns +0 for n > 0.
F.10.4.3 [The fabs functions]
1 fabs(x) returns a value with the same bit representation as x, except with the sign bit set to 0
(positive), for all values of x (even quiet and signaling NaNs).
2 — fabs(±0) returns +0.
— fabs(±∞) returns +∞.
3 fabs(x) raises no floating-point exceptions, even if x is a signaling NaN. The returned value is
independent of the current rounding direction mode.
F.10.4.4 [The hypot functions]
1 — hypot(x, y), hypot(y, x), and hypot(x, −y) are equivalent.
— hypot(x, ±0) returns the absolute value of x, if x is not a NaN.
— hypot(±∞, y) returns +∞, even if y is a NaN.
— hypot(x, NaN) returns a NaN, if x is not ±∞.
F.10.4.5 [The pow functions]
1 — pow(±0, y) returns ±∞ and raises the "divide-by-zero" floating-point exception for y an odd
integer < 0.
— pow(±0, y) returns +∞ and raises the "divide-by-zero" floating-point exception for y < 0,
finite, and not an odd integer.
— pow(±0, −∞) returns +∞.
— pow(±0, y) returns ±0 for y an odd integer > 0.
— pow(±0, y) returns +0 for y > 0 and not an odd integer.
— pow(−1, ±∞) returns 1.
— pow(+1, y) returns 1 for any y, even a NaN.
— pow(x, ±0) returns 1 for any x, even a NaN.
— pow(x, y) returns a NaN and raises the "invalid" floating-point exception for finite x < 0 and
finite non-integer y.
— pow(x, −∞) returns +∞ for |x| < 1.
— pow(x, −∞) returns +0 for |x| > 1.
— pow(x, +∞) returns +0 for |x| < 1.
— pow(x, +∞) returns +∞ for |x| > 1.
— pow(−∞, y) returns −0 for y an odd integer < 0.
— pow(−∞, y) returns +0 for y < 0 and not an odd integer.
— pow(−∞, y) returns −∞ for y an odd integer > 0.
— pow(−∞, y) returns +∞ for y > 0 and not an odd integer.
— pow(+∞, y) returns +0 for y < 0.
— pow(+∞, y) returns +∞ for y > 0.
F.10.4.6 [The pown functions]
1 — pown(x, 0) returns 1 for all x not a signalling NaN.
— pown(±0, n) returns ±∞ and raises the "divide-by-zero" floating-point exception for odd
n < 0.
— pown(±0, n) returns +∞ and raises the "divide-by-zero" floating-point exception for even
n < 0.
— pown(±0, n) returns +0 for even n > 0.
— pown(±0, n) returns ±0 for odd n > 0.
— pown(±∞, n) is equivalent to pown(±0, −n) for n not 0, except that the "divide-by-zero"
floating-point exception is not raised.
F.10.4.7 [The powr functions]
1 — powr(x, ±0) returns 1 for finite x > 0.
— powr(±0, y) returns +∞ and raises the "divide-by-zero" floating-point exception for finite
y < 0.
— powr(±0, −∞) returns +∞.
— powr(±0, y) returns +0 for y > 0.
— powr(+1, y) returns 1 for finite y.
— powr(+1, y)
— powr(x, y) returns a NaN and raises the "invalid" floating-point exception for x < 0.
— powr(±0, ±0) returns a NaN and raises the "invalid" floating-point exception.
— powr(+∞, ±0) returns a NaN and raises the "invalid" floating-point exception.
F.10.4.8 [The rootn functions]
1 — rootn(±0, n) returns ±∞ and raises the "divide-by-zero" floating-point exception for odd
n < 0.
— rootn(±0, n) returns +∞ and raises the "divide-by-zero" floating-point exception for even
n < 0.
— rootn(±0, n) returns +0 for even n > 0.
— rootn(±0, n) returns ±0 for odd n > 0.
— rootn(+∞, n) returns +∞ for n > 0.
— rootn(−∞, n) returns −∞ for odd n > 0.
— rootn(−∞, n) returns a NaN and raises the "invalid" floating-point exception for even n > 0.
— rootn(+∞, n) returns +0 for n < 0.
— rootn(−∞, n) returns −0 for odd n < 0.
— rootn(−∞, n) returns a NaN and raises the "invalid" floating-point exception for even n < 0.
— rootn(x, 0) returns a NaN and raises the "invalid" floating-point exception for all x (including
NaN).
— rootn(x, n) returns a NaN and raises the "invalid" floating-point exception for x < 0 and n
even.
F.10.4.9 [The rsqrt functions]
1 — rsqrt(±0) returns ±∞ and raises the "divide-by-zero" floating-point exception.
— rsqrt(x) returns a NaN and raises the "invalid" floating-point exception for x < 0.
— rsqrt(+∞) returns +0.
F.10.4.10 [The sqrt functions]
1 — sqrt(±0) returns ±0.
— sqrt(+∞) returns +∞.
— sqrt(x) returns a NaN and raises the "invalid" floating-point exception for x < 0.
2 The returned value is dependent on the current rounding direction mode.
F.10.5 [Error and gamma functions]
F.10.5.1 [The erf functions]
1 — erf(±0) returns ±0.
— erf(±∞) returns ±1.
F.10.5.2 [The erfc functions]
1 — erfc(−∞) returns 2.
— erfc(+∞) returns +0.
F.10.5.3 [The lgamma functions]
1 — lgamma(1) returns +0.
— lgamma(2) returns +0.
— lgamma(x) returns +∞ and raises the "divide-by-zero" floating-point exception for x a negative
integer or zero.
— lgamma(−∞) returns +∞.
— lgamma(+∞) returns +∞.
F.10.5.4 [The tgamma functions]
1 — tgamma(±0) returns ±∞ and raises the "divide-by-zero" floating-point exception.
— tgamma(x) returns a NaN and raises the "invalid" floating-point exception for x a negative
integer.
— tgamma(−∞) returns a NaN and raises the "invalid" floating-point exception.
— tgamma(+∞) returns +∞.
F.10.6 [Nearest integer functions]
F.10.6.1 [The ceil functions]
1 — ceil(±0) returns ±0.
— ceil(±∞) returns ±∞.
2 The returned value is exact and is independent of the current rounding direction mode.
3 The double version of ceil behaves as though implemented by
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
double ceil(double x)
{
double result;
int save_round = fegetround();
fesetround(FE_UPWARD);
result = nearbyint(x);
fesetround(save_round);
return result;
}
F.10.6.2 [The floor functions]
1 — floor(±0) returns ±0.
— floor(±∞) returns ±∞.
2 The returned value is exact and is independent of the current rounding direction mode.
3 See the sample implementation for ceil in F.10.6.1.
F.10.6.3 [The nearbyint functions]
1 The nearbyint functions use IEC 60559 rounding according to the current rounding direction. They
do not raise the "inexact" floating-point exception if the result differs in value from the argument.
— nearbyint(±0) returns ±0 (for all rounding directions).
— nearbyint(±∞) returns ±∞ (for all rounding directions).
F.10.6.4 [The rint functions]
1 The rint functions differ from the nearbyint functions only in that they do raise the "inexact"
floating-point exception if the result differs in value from the argument.
F.10.6.5 [The lrint and llrint functions]
1 The lrint and llrint functions provide floating-to-integer conversion as prescribed by IEC 60559.
They round according to the current rounding direction. If the rounded value is outside the range of
the return type, the numeric result is unspecified and the "invalid" floating-point exception is raised.
When they raise no other floating-point exception and the result differs from the argument, they
raise the "inexact" floating-point exception.
F.10.6.6 [The round functions]
1 — round(±0) returns ±0.
— round(±∞) returns ±∞.
2 The returned value is independent of the current rounding direction mode.
3 The double version of round behaves as though implemented by[455]
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
double round(double x)
{
double result;
fenv_t save_env;
feholdexcept(&save_env);
result = rint(x);
if (fetestexcept(FE_INEXACT)) {
fesetround(FE_TOWARDZERO);
result = rint(copysign(0.5 + fabs(x), x));
feclearexcept(FE_INEXACT);
}
feupdateenv(&save_env);
return result;
}
Footnote 455) This code does not handle signaling NaNs as required of implementations that define FE_SNANS_ALWAYS_SIGNAL.
F.10.6.7 [The lround and llround functions]
1 The lround and llround functions differ from the lrint and llrint functions with the default
rounding direction just in that the lround and llround functions round halfway cases away from
zero and need not raise the "inexact" floating-point exception for non-integer arguments that round
to within the range of the return type.
F.10.6.8 [The roundeven functions]
1
— roundeven(±0) returns ±0.
— roundeven(±∞) returns ±∞.
2 The returned value is exact and is independent of the current rounding direction mode.
3 See the sample implementation for ceil in F.10.6.1.
F.10.6.9 [The trunc functions]
1 The trunc functions use IEC 60559 rounding toward zero (regardless of the current rounding
direction).
— trunc(±0) returns ±0.
— trunc(±∞) returns ±∞.
2 The returned value is exact and is independent of the current rounding direction mode.
F.10.6.10 [The fromfp and ufromfp functions]
1 The fromfp and ufromfp functions raise the "invalid" floating-point exception and return a NaN
if the argument width is zero or if the floating-point argument x is infinite or NaN or rounds to an
integral value that is outside the range determined by the argument width (see <IP_ADDRESS>).
2 These functions do not raise the "inexact" floating-point exception.
F.10.6.11 [The fromfpx and ufromfpx functions]
1 The fromfpx and ufromfpx functions raise the "invalid" floating-point exception and return a NaN
if the argument width is zero or if the floating-point argument x is infinite or NaN or rounds to an
integral value that is outside the range determined by the argument width (see <IP_ADDRESS>).
2 These functions raise the "inexact" floating-point exception if a valid result differs in value from the
floating-point argument x.
F.10.7 [Remainder functions]
F.10.7.1 [The fmod functions]
1 — fmod(±0, y) returns ±0 for y not zero.
— fmod(x, y) returns a NaN and raises the "invalid" floating-point exception for x infinite or y
zero (and neither is a NaN).
— fmod(x, ±∞) returns x for x finite x.
2 When subnormal results are supported, the returned value is exact and is independent of the current
rounding direction mode.
3 The double version of fmod behaves as though implemented by
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
double fmod(double x, double y)
{
double result;
result = remainder(fabs(x), (y = fabs(y)));
if (signbit(result)) result += y;
return copysign(result, x);
}
F.10.7.2 [The remainder functions]
1 — remainder(±0, y) returns ±0 for y not zero.
— remainder(x, y) returns a NaN and raises the "invalid" floating-point exception for x infinite
or y zero (and neither is a NaN).
— remainder(x, ±∞) returns x for finite x.
2 When subnormal results are supported, the returned value is exact and is independent of the current
rounding direction mode.
F.10.7.3 [The remquo functions]
1 The remquo functions follow the specifications for the remainder functions.
2 If a NaN is returned, the value stored in the object pointed to by quo is unspecified.
3 When subnormal results are supported, the returned value is exact and is independent of the current
rounding direction mode.
F.10.8 [Manipulation functions]
F.10.8.1 [The copysign functions]
1 copysign(x, y) returns a value with the bit representation of x , except with the sign bit of y, for all
values x and y (even quiet and signaling NaNs).
2 copysign(x, y) raises no floating-point exceptions, even if x or y is a signaling NaN. The returned
value is independent of the current rounding direction mode.
F.10.8.2 [The nan functions]
1 All IEC 60559 implementations support quiet NaNs, in all floating formats.
2 The returned value is exact and is independent of the current rounding direction mode.
F.10.8.3 [The nextafter functions]
1 — nextafter(x, y) raises the "overflow" and "inexact" floating-point exceptions for x finite and
the function value infinite.
— nextafter(x, y) raises the "underflow" and "inexact" floating-point exceptions for the func-
tion value subnormal or zero and x ̸= y.
2 Even though underflow or overflow can occur, the returned value is independent of the current
rounding direction mode.
F.10.8.4 [The nexttoward functions]
1 No additional requirements beyond those on nextafter.
2 Even though underflow or overflow can occur, the returned value is independent of the current
rounding direction mode.
F.10.8.5 [The nextup functions]
1 — nextup(+∞) returns +∞.
— nextup(−∞) returns the largest-magnitude negative finite number in the type of the function.
2 nextup(x) raises no floating-point exceptions if x is not a signaling NaN. The returned value is
independent of the current rounding direction mode.
F.10.8.6 [The nextdown functions]
1 — nextdown(−∞) returns −∞.
— nextdown(+∞) returns the largest-magnitude positive finite number in the type of the func-
tion.
2 nextdown(x) raises no floating-point exceptions if x is not a signaling NaN. The returned value is
independent of the current rounding direction mode.
F.10.8.7 [The canonicalize functions]
1 The canonicalize functions produce[456] the canonical version of the representation in the object
pointed to by the argument x. If the input *x is a signaling NaN, the "invalid" floating-point
exception is raised and a (canonical) quiet NaN (which should be the canonical version of that
signaling NaN made quiet) is produced. For quiet NaN, infinity, and finite inputs, the functions
raise no floating-point exceptions.
Footnote 456) As if *x * 1e0 were computed. Note also that this implementation does not handle signaling NaNs as required of
implementations that define FE_SNANS_ALWAYS_SIGNAL.
F.10.9 [Maximum, minimum, and positive difference functions]
F.10.9.1 [The fdim functions]
1 No additional requirements.
F.10.9.2 [The fmax functions]
1 If just one argument is a NaN, the fmax functions return the other argument (if both arguments are
NaNs, the functions return a NaN).
2 The returned value is exact and is independent of the current rounding direction mode.
3 The body of the fmax function might be[457]
{
double r = (isgreaterequal(x, y) || isnan(y)) ? x : y;
(void) canonicalize(&r, &r);
return r;
}
Footnote 457) Ideally, fmax would be sensitive to the sign of zero, for example fmax(−0.0, +0.0) would return +0; however, implemen-
tation in software might be impractical.
F.10.9.3 [The fmin functions]
1 The fmin functions are analogous to the fmax functions (see F.10.9.2).
2 The returned value is exact and is independent of the current rounding direction mode.
F.10.9.4 [The fmaximum, fminimum, fmaximum_mag, and fminimum_mag functions]
1 These functions treat NaNs like other functions in <math.h> (see F.10). They differ from the cor-
responding fmaximum_num, fminimum_num, fmaximum_mag_num, and fminimum_mag_num functions
only in their treatment of NaNs.
F.10.9.5 [The fmaximum_num, fminimum_num, fmaximum_mag_num, and fminimum_mag_num func-]
1 tions
These functions return the number if one argument is a number and the other is a quiet or signaling
NaN. If both arguments are NaNs, a quiet NaN is returned. If an argument is a signaling NaN, the
"invalid" floating-point exception is raised (even though the function returns the number when the
other argument is a number).
F.10.10 [Fused multiply-add]
F.10.10.1 [The fma functions]
1 — fma(x, y, z) computes xy + z, correctly rounded once.
— fma(x, y, z) returns a NaN and optionally raises the "invalid" floating-point exception if one
of x and y is infinite, the other is zero, and z is a NaN.
— fma(x, y, z) returns a NaN and raises the "invalid" floating-point exception if one of x and y is
infinite, the other is zero, and z is not a NaN.
— fma(x, y, z) returns a NaN and raises the "invalid" floating-point exception if x times y is an
exact infinity and z is also an infinity but with the opposite sign.
F.10.11 [Functions that round result to narrower type]
1 The functions that round their result to narrower type (7.12.14) are fully specified in IEC 60559. The
returned value is dependent on the current rounding direction mode.
2 These functions treat zero and infinite arguments like the corresponding operation or function: + ,- ,
* , / , fma, or sqrt.
F.10.12 [Total order functions]
1 This subclause specifies the total order functions required by IEC 60559.
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.12.1 [The totalorder functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_EXT__
#include <math.h>
#ifdef __STDC_IEC_60559_BFP__
int totalorder(const double *x, const double *y);
int totalorderf(const float *x, const float *y);
int totalorderl(const long double *x, const long double *y);
#endif
#ifdef __STDC_IEC_60559_DFP__
int totalorderd32(const _Decimal32 *x, const _Decimal32 *y);
int totalorderd64(const _Decimal64 *x, const _Decimal64 *y);
int totalorderd128(const _Decimal128 *x, const _Decimal128 *y);
#endif
Description
2 The totalorder functions determine whether the total order relationship, defined by IEC 60559, is
true for the ordered pair 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 totalorder functions return nonzero if and only if the total order relation is true for the ordered
pair of *x , *y .
F.10.12.2 [The totalordermag functions]
1 Synopsis
#define __STDC_WANT_IEC_60559_EXT__
#include <math.h>
#ifdef __STDC_IEC_60559_BFP__
int totalordermag(const double *x, const double *y);
int totalordermagf(const float *x, const float *y);
int totalordermagl(const long double *x, const long double *y);
#endif
#ifdef __STDC_IEC_60559_DFP__
int totalordermagd32(const _Decimal32 *x, const _Decimal32 *y);
int totalordermagd64(const _Decimal64 *x, const _Decimal64 *y);
int totalordermagd128(const _Decimal128 *x, const _Decimal128 *y);
#endif
Description
2 The totalordermag functions determine whether the total order relationship, defined by IEC 60559,