Programming languages — C (INTERNATIONAL STANDARD ISO/IEC 9899:TC3) - page 14

 

  Главная      Manuals     Programming languages — C (INTERNATIONAL STANDARD ISO/IEC 9899:TC3) - 2007 year

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     12      13      14      15     ..

 

 

 

Programming languages — C (INTERNATIONAL STANDARD ISO/IEC 9899:TC3) - page 14

 

 

Annex G

(informative)

IEC 60559-compatible complex arithmetic

G.1 Introduction

1

This annex supplements annex F to specify complex arithmetic for compatibility with
IEC 60559 real floating-point arithmetic. Although these specifications have been
carefully designed, there is little existing practice to validate the design decisions.
Therefore, these specifications are not normative, but should be viewed more as
recommended practice.

An implementation that defines

_ _STDC_IEC_559_COMPLEX_ _

should conform to the specifications in this annex.

G.2 Types

1

There is a new keyword

_Imaginary

, which is used to specify imaginary types. It is

used as a type specifier within declaration specifiers in the same way as

_Complex

is

(thus,

_Imaginary float

is a valid type name).

2

There are three imaginary types, designated as

float _Imaginary

,

double

_Imaginary

, and

long double _Imaginary

. The imaginary types (along with

the real floating and complex types) are floating types.

3

For imaginary types, the corresponding real type is given by deleting the keyword

_Imaginary

from the type name.

4

Each imaginary type has the same representation and alignment requirements as the
corresponding real type. The value of an object of imaginary type is the value of the real
representation times the imaginary unit.

5

The imaginary type domain comprises the imaginary types.

G.3 Conventions

1

A complex or imaginary value with at least one infinite part is regarded as an infinity
(even if its other part is a NaN). A complex or imaginary value is a finite number if each
of its parts is a finite number (neither infinite nor NaN). A complex or imaginary value is
zero if each of its parts is a zero.

§G.3 IEC 60559-compatible complex arithmetic 467

G.4 Conversions

G.4.1 Imaginary types

1

Conversions among imaginary types follow rules analogous to those for real floating
types.

G.4.2 Real and imaginary

1

When a value of imaginary type is converted to a real type other than

_Bool

,

324)

the

result is a positive zero.

2

When a value of real type is converted to an imaginary type, the result is a positive
imaginary zero.

G.4.3 Imaginary and complex

1

When a value of imaginary type is converted to a complex type, the real part of the
complex result value is a positive zero and the imaginary part of the complex result value
is determined by the conversion rules for the corresponding real types.

2

When a value of complex type is converted to an imaginary type, the real part of the
complex value is discarded and the value of the imaginary part is converted according to
the conversion rules for the corresponding real types.

G.5 Binary operators

1

The following subclauses supplement 6.5 in order to specify the type of the result for an
operation with an imaginary operand.

2

For most operand types, the value of the result of a binary operator with an imaginary or
complex operand is completely determined, with reference to real arithmetic, by the usual
mathematical formula. For some operand types, the usual mathematical formula is
problematic because of its treatment of infinities and because of undue overflow or
underflow; in these cases the result satisfies certain properties (specified in G.5.1), but is
not completely determined.

324) See 6.3.1.2.

468 IEC 60559-compatible complex arithmetic §G.5

G.5.1 Multiplicative operators

Semantics

1

If one operand has real type and the other operand has imaginary type, then the result has
imaginary type. If both operands have imaginary type, then the result has real type. (If
either operand has complex type, then the result has complex type.)

2

If the operands are not both complex, then the result and floating-point exception
behavior of the

*

operator is defined by the usual mathematical formula:

*

u

iv

u

+

iv

x

xu

i(xv)

(xu)

+

i(xv)

iy i(yu)

yv

(

yv)

+

i(yu)

x

+

iy

(xu)

+

i(yu)

(

yv)

+

i(xv)

3

If the second operand is not complex, then the result and floating-point exception
behavior of the

/

operator is defined by the usual mathematical formula:

/

u

iv

x

x/u

i(

x/v)

iy i(y/u)

y/v

x

+

iy

(x/u)

+

i(y/u)

(y/v)

+

i(

x/v)

4

The

*

and

/

operators satisfy the following infinity properties for all real, imaginary, and

complex operands:

325)

— if one operand is an infinity and the other operand is a nonzero finite number or an

infinity, then the result of the

*

operator is an infinity;

— if the first operand is an infinity and the second operand is a finite number, then the

result of the

/

operator is an infinity;

— if the first operand is a finite number and the second operand is an infinity, then the

result of the

/

operator is a zero;

325) These properties are already implied for those cases covered in the tables, but are required for all cases

(at least where the state for

CX_LIMITED_RANGE

is ‘‘off’’).

§G.5.1 IEC 60559-compatible complex arithmetic 469

— if the first operand is a nonzero finite number or an infinity and the second operand is

a zero, then the result of the

/

operator is an infinity.

5

If both operands of the

*

operator are complex or if the second operand of the

/

operator

is complex, the operator raises floating-point exceptions if appropriate for the calculation
of the parts of the result, and may raise spurious floating-point exceptions.

6

EXAMPLE 1

Multiplication of

double _Complex

operands could be implemented as follows. Note

that the imaginary unit

I

has imaginary type (see G.6).

#include <math.h>

#include <complex.h>

/*

Multiply

z * w

...

*/

double complex _Cmultd(double complex z, double complex w)

{

#pragma STDC FP_CONTRACT OFF

double a, b, c, d, ac, bd, ad, bc, x, y;

a = creal(z); b = cimag(z);

c = creal(w); d = cimag(w);

ac = a * c;

bd = b * d;

ad = a * d;

bc = b * c;

x = ac - bd; y = ad + bc;

if (isnan(x) && isnan(y)) {

/*

Recover infinities that computed as NaN+iNaN ...

*/

int recalc = 0;

if ( isinf(a) || isinf(b) ) { // z

is infinite

/*

"Box" the infinity and change NaNs in the other factor to 0

*/

a = copysign(isinf(a) ? 1.0 : 0.0, a);

b = copysign(isinf(b) ? 1.0 : 0.0, b);

if (isnan(c)) c = copysign(0.0, c);

if (isnan(d)) d = copysign(0.0, d);

recalc = 1;

}

if ( isinf(c) || isinf(d) ) { // w

is infinite

/*

"Box" the infinity and change NaNs in the other factor to 0

*/

c = copysign(isinf(c) ? 1.0 : 0.0, c);

d = copysign(isinf(d) ? 1.0 : 0.0, d);

if (isnan(a)) a = copysign(0.0, a);

if (isnan(b)) b = copysign(0.0, b);

recalc = 1;

}

if (!recalc && (isinf(ac) || isinf(bd) ||

isinf(ad) || isinf(bc))) {

/*

Recover infinities from overflow by changing NaNs to 0 ...

*/

if (isnan(a)) a = copysign(0.0, a);

if (isnan(b)) b = copysign(0.0, b);

if (isnan(c)) c = copysign(0.0, c);

if (isnan(d)) d = copysign(0.0, d);

recalc = 1;

}

if (recalc) {

470 IEC 60559-compatible complex arithmetic §G.5.1

x = INFINITY * ( a * c - b * d );

y = INFINITY * ( a * d + b * c );

}

}

return x + I * y;

}

7

This implementation achieves the required treatment of infinities at the cost of only one

isnan

test in

ordinary (finite) cases. It is less than ideal in that undue overflow and underflow may occur.

8

EXAMPLE 2

Division of two

double _Complex

operands could be implemented as follows.

#include <math.h>

#include <complex.h>

/*

Divide

z / w

...

*/

double complex _Cdivd(double complex z, double complex w)

{

#pragma STDC FP_CONTRACT OFF

double a, b, c, d, logbw, denom, x, y;

int ilogbw = 0;

a = creal(z); b = cimag(z);

c = creal(w); d = cimag(w);

logbw = logb(fmax(fabs(c), fabs(d)));

if (isfinite(logbw)) {

ilogbw = (int)logbw;

c = scalbn(c, -ilogbw); d = scalbn(d, -ilogbw);

}

denom = c * c + d * d;

x = scalbn((a * c + b * d) / denom, -ilogbw);

y = scalbn((b * c - a * d) / denom, -ilogbw);

/*

Recover infinities and zeros that computed as NaN+iNaN;

*/

/*

the only cases are nonzero/zero, infinite/finite, and finite/infinite, ...

*/

if (isnan(x) && isnan(y)) {

if ((denom == 0.0) &&

(!isnan(a) || !isnan(b))) {

x = copysign(INFINITY, c) * a;

y = copysign(INFINITY, c) * b;

}

else if ((isinf(a) || isinf(b)) &&

isfinite(c) && isfinite(d)) {

a = copysign(isinf(a) ? 1.0 : 0.0, a);

b = copysign(isinf(b) ? 1.0 : 0.0, b);

x = INFINITY * ( a * c + b * d );

y = INFINITY * ( b * c - a * d );

}

else if (isinf(logbw) &&

isfinite(a) && isfinite(b)) {

c = copysign(isinf(c) ? 1.0 : 0.0, c);

d = copysign(isinf(d) ? 1.0 : 0.0, d);

x = 0.0 * ( a * c + b * d );

y = 0.0 * ( b * c - a * d );

§G.5.1 IEC 60559-compatible complex arithmetic 471

}

}

return x + I * y;

}

9

Scaling the denominator alleviates the main overflow and underflow problem, which is more serious than
for multiplication. In the spirit of the multiplication example above, this code does not defend against
overflow and underflow in the calculation of the numerator. Scaling with the

scalbn

function, instead of

with division, provides better roundoff characteristics.

G.5.2 Additive operators

Semantics

1

If both operands have imaginary type, then the result has imaginary type. (If one operand
has real type and the other operand has imaginary type, or if either operand has complex
type, then the result has complex type.)

2

In all cases the result and floating-point exception behavior of a

+

or

-

operator is defined

by the usual mathematical formula:

+

or

u

iv

u

+

iv

x

x

±

u

x

±

iv

(x

±

u)

±

iv

iy

±

u

+

iy i(y

±

v)

±

u

+

i(y

±

v)

x

+

iy

(x

±

u)

+

iy x

+

i(y

±

v)

(x

±

u)

+

i(y

±

v)

G.6 Complex arithmetic

<complex.h>

1

The macros

imaginary

and

_Imaginary_I

are defined, respectively, as

_Imaginary

and a constant expression of type

const

float _Imaginary

with the value of the imaginary unit. The macro

I

is defined to be

_Imaginary_I

(not

_Complex_I

as stated in 7.3). Notwithstanding

the provisions of 7.1.3, a program may undefine and then perhaps redefine the macro

imaginary

.

2

This subclause contains specifications for the

<complex.h>

functions that are

particularly suited to IEC 60559 implementations.

For families of functions, the

specifications apply to all of the functions even though only the principal function is

472 IEC 60559-compatible complex arithmetic §G.6

shown. Unless otherwise specified, where the symbol ‘‘

±

’’ occurs in both an argument

and the result, the result has the same sign as the argument.

3

The functions are continuous onto both sides of their branch cuts, taking into account the

sign of zero. For example,

csqrt(

2

±

i0

)

= ±

i

√

2.

4

Since complex and imaginary values are composed of real values, each function may be
regarded as computing real values from real values. Except as noted, the functions treat
real infinities, NaNs, signed zeros, subnormals, and the floating-point exception flags in a
manner consistent with the specifications for real functions in F.9.

326)

5

The functions

cimag

,

conj

,

cproj

, and

creal

are fully specified for all

implementations, including IEC 60559 ones, in 7.3.9. These functions raise no floating-
point exceptions.

6

Each of the functions

cabs

and

carg

is specified by a formula in terms of a real

function (whose special cases are covered in annex F):

cabs(

x

+

iy

)

=

hypot(

x

,

y

)

carg(

x

+

iy

)

=

atan2(

y

,

x

)

7

Each of the functions

casin

,

catan

,

ccos

,

csin

, and

ctan

is specified implicitly by

a formula in terms of other complex functions (whose special cases are specified below):

casin(

z

)

= −

i

casinh(

iz

)

catan(

z

)

= −

i

catanh(

iz

)

ccos(

z

)

=

ccosh(

iz

)

csin(

z

)

= −

i

csinh(

iz

)

ctan(

z

)

= −

i

ctanh(

iz

)

8

For the other functions, the following subclauses specify behavior for special cases,
including treatment of the ‘‘invalid’’ and ‘‘divide-by-zero’’ floating-point exceptions. For
families of functions, the specifications apply to all of the functions even though only the
principal function is shown. For a function satisfying (conj(z))

=

conj( (z)), the

specifications for the upper half-plane imply the specifications for the lower half-plane; if
the function is also either even, (

z)

=

(z), or odd, (

z)

= −

(z), then the

specifications for the first quadrant imply the specifications for the other three quadrants.

9

In the following subclauses, cis(y) is defined as cos(y)

+

sin(y).

326) As noted in G.3, a complex value with at least one infinite part is regarded as an infinity even if its

other part is a NaN.

§G.6 IEC 60559-compatible complex arithmetic 473

G.6.1 Trigonometric functions

G.6.1.1 The

cacos

functions

1

cacos(conj(

z

))

=

conj(cacos(

z

))

.

cacos(

±

0

+

i0

)

returns

π

/2

i0.

cacos(

±

0

+

iNaN

)

returns

π

/2

+

iNaN.

cacos(

x

+

i

)

returns

π

/2

i

, for finite x.

cacos(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for nonzero finite x.

cacos(

+

iy

)

returns

π

i

, for positive-signed finite y.

cacos(

+

+

iy

)

returns

+

0

i

, for positive-signed finite y.

cacos(

+

i

)

returns 3

π

/4

i

.

cacos(

+

+

i

)

returns

π

/4

i

.

cacos(

±

+

iNaN

)

returns NaN

±

i

(where the sign of the imaginary part of the

result is unspecified).

cacos(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite y.

cacos(

NaN

+

i

)

returns NaN

i

.

cacos(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.2 Hyperbolic functions

G.6.2.1 The

cacosh

functions

1

cacosh(conj(

z

))

=

conj(cacosh(

z

))

.

cacosh(

±

0

+

i0

)

returns

+

0

+

i

π

/2.

cacosh(

x

+

i

)

returns

+

+

i

π

/2, for finite x.

cacosh(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’

floating-point exception, for finite x.

cacosh(

+

iy

)

returns

+

+

i

π

, for positive-signed finite y.

cacosh(

+

+

iy

)

returns

+

+

i0, for positive-signed finite y.

cacosh(

+

i

)

returns

+

+

i3

π

/4.

cacosh(

+

+

i

)

returns

+

+

i

π

/4.

cacosh(

±

+

iNaN

)

returns

+

+

iNaN.

474 IEC 60559-compatible complex arithmetic §G.6.2.1

cacosh(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’

floating-point exception, for finite y.

cacosh(

NaN

+

i

)

returns

+

+

iNaN.

cacosh(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.2.2 The

casinh

functions

1

casinh(conj(

z

))

=

conj(casinh(

z

))

and

casinh

is odd.

casinh(

+

0

+

i0

)

returns 0

+

i0.

casinh(

x

+

i

)

returns

+

+

i

π

/2 for positive-signed finite x.

casinh(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’

floating-point exception, for finite x.

casinh(

+

+

iy

)

returns

+

+

i0 for positive-signed finite y.

casinh(

+

+

i

)

returns

+

+

i

π

/4.

casinh(

+

+

iNaN

)

returns

+

+

iNaN.

casinh(

NaN

+

i0

)

returns NaN

+

i0.

casinh(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’

floating-point exception, for finite nonzero y.

casinh(

NaN

+

i

)

returns

±

+

iNaN (where the sign of the real part of the result

is unspecified).

casinh(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.2.3 The

catanh

functions

1

catanh(conj(

z

))

=

conj(catanh(

z

))

and

catanh

is odd.

catanh(

+

0

+

i0

)

returns

+

0

+

i0.

catanh(

+

0

+

iNaN

)

returns

+

0

+

iNaN.

catanh(

+

1

+

i0

)

returns

+

+

i0 and raises the ‘‘divide-by-zero’’ floating-point

exception.

catanh(

x

+

i

)

returns

+

0

+

i

π

/2, for finite positive-signed x.

catanh(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’

floating-point exception, for nonzero finite x.

catanh(

+

+

iy

)

returns

+

0

+

i

π

/2, for finite positive-signed y.

catanh(

+

+

i

)

returns

+

0

+

i

π

/2.

catanh(

+

+

iNaN

)

returns

+

0

+

iNaN.

§G.6.2.3 IEC 60559-compatible complex arithmetic 475

catanh(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’

floating-point exception, for finite y.

catanh(

NaN

+

i

)

returns

±

0

+

i

π

/2 (where the sign of the real part of the result is

unspecified).

catanh(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.2.4 The

ccosh

functions

1

ccosh(conj(

z

))

=

conj(ccosh(

z

))

and

ccosh

is even.

ccosh(

+

0

+

i0

)

returns 1

+

i0.

ccosh(

+

0

+

i

)

returns NaN

±

i0 (where the sign of the imaginary part of the

result is unspecified) and raises the ‘‘invalid’’ floating-point exception.

ccosh(

+

0

+

iNaN

)

returns NaN

±

i0 (where the sign of the imaginary part of the

result is unspecified).

ccosh(

x

+

i

)

returns NaN

+

iNaN and raises the ‘‘invalid’’ floating-point

exception, for finite nonzero x.

ccosh(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite nonzero x.

ccosh(

+

+

i0

)

returns

+

+

i0.

ccosh(

+

+

iy

)

returns

+

cis(y), for finite nonzero y.

ccosh(

+

+

i

)

returns

±

+

iNaN (where the sign of the real part of the result is

unspecified) and raises the ‘‘invalid’’ floating-point exception.

ccosh(

+

+

iNaN

)

returns

+

+

iNaN.

ccosh(

NaN

+

i0

)

returns NaN

±

i0 (where the sign of the imaginary part of the

result is unspecified).

ccosh(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for all nonzero numbers y.

ccosh(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.2.5 The

csinh

functions

1

csinh(conj(

z

))

=

conj(csinh(

z

))

and

csinh

is odd.

csinh(

+

0

+

i0

)

returns

+

0

+

i0.

csinh(

+

0

+

i

)

returns

±

0

+

iNaN (where the sign of the real part of the result is

unspecified) and raises the ‘‘invalid’’ floating-point exception.

csinh(

+

0

+

iNaN

)

returns

±

0

+

iNaN (where the sign of the real part of the result is

unspecified).

476 IEC 60559-compatible complex arithmetic §G.6.2.5

csinh(

x

+

i

)

returns NaN

+

iNaN and raises the ‘‘invalid’’ floating-point

exception, for positive finite x.

csinh(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite nonzero x.

csinh(

+

+

i0

)

returns

+

+

i0.

csinh(

+

+

iy

)

returns

+

cis(y), for positive finite y.

csinh(

+

+

i

)

returns

±

+

iNaN (where the sign of the real part of the result is

unspecified) and raises the ‘‘invalid’’ floating-point exception.

csinh(

+

+

iNaN

)

returns

±

+

iNaN (where the sign of the real part of the result

is unspecified).

csinh(

NaN

+

i0

)

returns NaN

+

i0.

csinh(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for all nonzero numbers y.

csinh(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.2.6 The

ctanh

functions

1

ctanh(conj(

z

))

=

conj(ctanh(

z

))

and

ctanh

is odd.

ctanh(

+

0

+

i0

)

returns

+

0

+

i0.

ctanh(

x

+

i

)

returns NaN

+

iNaN and raises the ‘‘invalid’’ floating-point

exception, for finite x.

ctanh(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite x.

ctanh(

+

+

iy

)

returns 1

+

i0 sin(2y), for positive-signed finite y.

ctanh(

+

+

i

)

returns 1

±

i0 (where the sign of the imaginary part of the result

is unspecified).

ctanh(

+

+

iNaN

)

returns 1

±

i0 (where the sign of the imaginary part of the

result is unspecified).

ctanh(

NaN

+

i0

)

returns NaN

+

i0.

ctanh(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for all nonzero numbers y.

ctanh(

NaN

+

iNaN

)

returns NaN

+

iNaN.

§G.6.2.6 IEC 60559-compatible complex arithmetic 477

G.6.3 Exponential and logarithmic functions

G.6.3.1 The

cexp

functions

1

cexp(conj(

z

))

=

conj(cexp(

z

))

.

cexp(

±

0

+

i0

)

returns 1

+

i0.

cexp(

x

+

i

)

returns NaN

+

iNaN and raises the ‘‘invalid’’ floating-point

exception, for finite x.

cexp(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite x.

cexp(

+

+

i0

)

returns

+

+

i0.

cexp(

+

iy

)

returns

+

0 cis(y), for finite y.

cexp(

+

+

iy

)

returns

+

cis(y), for finite nonzero y.

cexp(

+

i

)

returns

±

0

±

i0 (where the signs of the real and imaginary parts of

the result are unspecified).

cexp(

+

+

i

)

returns

±

+

iNaN and raises the ‘‘invalid’’ floating-point

exception (where the sign of the real part of the result is unspecified).

cexp(

+

iNaN

)

returns

±

0

±

i0 (where the signs of the real and imaginary parts

of the result are unspecified).

cexp(

+

+

iNaN

)

returns

±

+

iNaN (where the sign of the real part of the result

is unspecified).

cexp(

NaN

+

i0

)

returns NaN

+

i0.

cexp(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for all nonzero numbers y.

cexp(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.3.2 The

clog

functions

1

clog(conj(

z

))

=

conj(clog(

z

))

.

clog(

0

+

i0

)

returns

+

i

π

and raises the ‘‘divide-by-zero’’ floating-point

exception.

clog(

+

0

+

i0

)

returns

+

i0 and raises the ‘‘divide-by-zero’’ floating-point

exception.

clog(

x

+

i

)

returns

+

+

i

π

/2, for finite x.

clog(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite x.

478 IEC 60559-compatible complex arithmetic §G.6.3.2

clog(

+

iy

)

returns

+

+

i

π

, for finite positive-signed y.

clog(

+

+

iy

)

returns

+

+

i0, for finite positive-signed y.

clog(

+

i

)

returns

+

+

i3

π

/4.

clog(

+

+

i

)

returns

+

+

i

π

/4.

clog(

±

+

iNaN

)

returns

+

+

iNaN.

clog(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite y.

clog(

NaN

+

i

)

returns

+

+

iNaN.

clog(

NaN

+

iNaN

)

returns NaN

+

iNaN.

G.6.4 Power and absolute-value functions

G.6.4.1 The

cpow

functions

1

The

cpow

functions raise floating-point exceptions if appropriate for the calculation of

the parts of the result, and may raise spurious exceptions.

327)

G.6.4.2 The

csqrt

functions

1

csqrt(conj(

z

))

=

conj(csqrt(

z

))

.

csqrt(

±

0

+

i0

)

returns

+

0

+

i0.

csqrt(

x

+

i

)

returns

+

+

i

, for all (including NaN).

csqrt(

x

+

iNaN

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite x.

csqrt(

+

iy

)

returns

+

0

+

i

, for finite positive-signed y.

csqrt(

+

+

iy

)

returns

+

+

i0, for finite positive-signed y.

csqrt(

+

iNaN

)

returns NaN

±

i

(where the sign of the imaginary part of the

result is unspecified).

csqrt(

+

+

iNaN

)

returns

+

+

iNaN.

csqrt(

NaN

+

iy

)

returns NaN

+

iNaN and optionally raises the ‘‘invalid’’ floating-

point exception, for finite y.

csqrt(

NaN

+

iNaN

)

returns NaN

+

iNaN.

327) This allows

cpow(

z

,

c

)

to be implemented as

cexp(

c

clog(

z

))

without precluding

implementations that treat special cases more carefully.

§G.6.4.2 IEC 60559-compatible complex arithmetic 479

G.7 Type-generic math

<tgmath.h>

1

Type-generic macros that accept complex arguments also accept imaginary arguments. If
an argument is imaginary, the macro expands to an expression whose type is real,
imaginary, or complex, as appropriate for the particular function: if the argument is
imaginary, then the types of

cos

,

cosh

,

fabs

,

carg

,

cimag

, and

creal

are real; the

types of

sin

,

tan

,

sinh

,

tanh

,

asin

,

atan

,

asinh

, and

atanh

are imaginary; and

the types of the others are complex.

2

Given an imaginary argument, each of the type-generic macros

cos

,

sin

,

tan

,

cosh

,

sinh

,

tanh

,

asin

,

atan

,

asinh

,

atanh

is specified by a formula in terms of real

functions:

cos(

iy

)

=

cosh(

y

)

sin(

iy

)

=

i

sinh(

y

)

tan(

iy

)

=

i

tanh(

y

)

cosh(

iy

)

=

cos(

y

)

sinh(

iy

)

=

i

sin(

y

)

tanh(

iy

)

=

i

tan(

y

)

asin(

iy

)

=

i

asinh(

y

)

atan(

iy

)

=

i

atanh(

y

)

asinh(

iy

)

=

i

asin(

y

)

atanh(

iy

)

=

i

atan(

y

)

480 IEC 60559-compatible complex arithmetic §G.7

Annex H

(informative)

Language independent arithmetic

H.1 Introduction

1

This annex documents the extent to which the C language supports the ISO/IEC 10967−1
standard for language-independent arithmetic (LIA−1). LIA−1 is more general than
IEC 60559 (annex F) in that it covers integer and diverse floating-point arithmetics.

H.2 Types

1

The relevant C arithmetic types meet the requirements of LIA−1 types if an
implementation adds notification of exceptional arithmetic operations and meets the 1
unit in the last place (ULP) accuracy requirement (LIA−1 subclause 5.2.8).

H.2.1 Boolean type

1

The LIA−1 data type Boolean is implemented by the C data type

bool

with values of

true

and

false

, all from

<stdbool.h>

.

H.2.2 Integer types

1

The signed C integer types

int

,

long int

,

long long int

, and the corresponding

unsigned types are compatible with LIA−1. If an implementation adds support for the
LIA−1 exceptional values ‘‘integer_overflow’’ and ‘‘undefined’’, then those types are
LIA−1 conformant types. C’s unsigned integer types are ‘‘modulo’’ in the LIA−1 sense
in that overflows or out-of-bounds results silently wrap. An implementation that defines
signed integer types as also being modulo need not detect integer overflow, in which case,
only integer divide-by-zero need be detected.

2

The parameters for the integer data types can be accessed by the following:

maxint

INT_MAX

,

LONG_MAX

,

LLONG_MAX

,

UINT_MAX

,

ULONG_MAX

,

ULLONG_MAX

minint

INT_MIN

,

LONG_MIN

,

LLONG_MIN

3

The parameter ‘‘bounded’’ is always true, and is not provided. The parameter ‘‘minint’’
is always 0 for the unsigned types, and is not provided for those types.

§H.2.2 Language independent arithmetic

481

H.2.2.1 Integer operations

1

The integer operations on integer types are the following:

addI

x + y

subI

x - y

mulI

x * y

divI, divtI

x / y

remI, remtI

x % y

negI

-x

absI

abs(x)

,

labs(x)

,

llabs(x)

eqI

x == y

neqI

x != y

lssI

x < y

leqI

x <= y

gtrI

x > y

geqI

x >= y

where

x

and

y

are expressions of the same integer type.

H.2.3 Floating-point types

1

The C floating-point types

float

,

double

, and

long double

are compatible with

LIA−1. If an implementation adds support for the LIA−1 exceptional values
‘‘underflow’’, ‘‘floating_overflow’’, and ‘‘"undefined’’, then those types are conformant
with LIA−1.

An implementation that uses IEC 60559 floating-point formats and

operations (see annex F) along with IEC 60559 status flags and traps has LIA−1
conformant types.

H.2.3.1 Floating-point parameters

1

The parameters for a floating point data type can be accessed by the following:

r

FLT_RADIX

p

FLT_MANT_DIG

,

DBL_MANT_DIG

,

LDBL_MANT_DIG

emax

FLT_MAX_EXP

,

DBL_MAX_EXP

,

LDBL_MAX_EXP

emin

FLT_MIN_EXP

,

DBL_MIN_EXP

,

LDBL_MIN_EXP

2

The derived constants for the floating point types are accessed by the following:

482 Language independent arithmetic

§H.2.3.1

fmax

FLT_MAX

,

DBL_MAX

,

LDBL_MAX

fminN

FLT_MIN

,

DBL_MIN

,

LDBL_MIN

epsilon

FLT_EPSILON

,

DBL_EPSILON

,

LDBL_EPSILON

rnd_style

FLT_ROUNDS

H.2.3.2 Floating-point operations

1

The floating-point operations on floating-point types are the following:

addF

x + y

subF

x - y

mulF

x * y

divF

x / y

negF

-x

absF

fabsf(x)

,

fabs(x)

,

fabsl(x)

exponentF

1.f+logbf(x)

,

1.0+logb(x)

,

1.L+logbl(x)

scaleF

scalbnf(x, n)

,

scalbn(x, n)

,

scalbnl(x, n)

,

scalblnf(x, li)

,

scalbln(x, li)

,

scalblnl(x, li)

intpartF

modff(x, &y)

,

modf(x, &y)

,

modfl(x, &y)

fractpartF

modff(x, &y)

,

modf(x, &y)

,

modfl(x, &y)

eqF

x == y

neqF

x != y

lssF

x < y

leqF

x <= y

gtrF

x > y

geqF

x >= y

where

x

and

y

are expressions of the same floating point type,

n

is of type

int

, and

li

is of type

long int

.

H.2.3.3 Rounding styles

1

The C Standard requires all floating types to use the same radix and rounding style, so
that only one identifier for each is provided to map to LIA−1.

2

The

FLT_ROUNDS

parameter can be used to indicate the LIA−1 rounding styles:

truncate

FLT_ROUNDS == 0

§H.2.3.3 Language independent arithmetic

483

nearest

FLT_ROUNDS == 1

other

FLT_ROUNDS != 0 && FLT_ROUNDS != 1

provided that an implementation extends

FLT_ROUNDS

to cover the rounding style used

in all relevant LIA−1 operations, not just addition as in C.

H.2.4 Type conversions

1

The LIA−1 type conversions are the following type casts:

cvtI’

I

(int)i

,

(long int)i

,

(long long int)i

,

(unsigned int)i

,

(unsigned long int)i

,

(unsigned long long int)i

cvtF

I

(int)x

,

(long int)x

,

(long long int)x

,

(unsigned int)x

,

(unsigned long int)x

,

(unsigned long long int)x

cvtI

F

(float)i

,

(double)i

,

(long double)i

cvtF’

F

(float)x

,

(double)x

,

(long double)x

2

In the above conversions from floating to integer, the use of

(

cast

)x

can be replaced with

(

cast

)round(x)

,

(

cast

)rint(x)

,

(

cast

)nearbyint(x)

,

(

cast

)trunc(x)

,

(

cast

)ceil(x)

, or

(

cast

)floor(x)

. In addition, C’s floating-point to integer

conversion functions,

lrint()

,

llrint()

,

lround()

, and

llround()

, can be

used. They all meet LIA−1’s requirements on floating to integer rounding for in-range
values. For out-of-range values, the conversions shall silently wrap for the modulo types.

3

The

fmod()

function is useful for doing silent wrapping to unsigned integer types, e.g.,

fmod( fabs(rint(x)), 65536.0 )

or

(0.0 <= (y = fmod( rint(x),

65536.0 )) ? y : 65536.0 + y)

will compute an integer value in the range 0.0

to 65535.0 which can then be cast to

unsigned short int

. But, the

remainder()

function is not useful for doing silent wrapping to signed integer types,

e.g.,

remainder( rint(x), 65536.0 )

will compute an integer value in the

range −32767.0 to +32768.0 which is not, in general, in the range of

signed short

int

.

4

C’s conversions (casts) from floating-point to floating-point can meet LIA−1
requirements if an implementation uses round-to-nearest (IEC 60559 default).

5

C’s conversions (casts) from integer to floating-point can meet LIA−1 requirements if an
implementation uses round-to-nearest.

484 Language independent arithmetic

§H.2.4

H.3 Notification

1

Notification is the process by which a user or program is informed that an exceptional
arithmetic operation has occurred. C’s operations are compatible with LIA−1 in that C
allows an implementation to cause a notification to occur when any arithmetic operation
returns an exceptional value as defined in LIA−1 clause 5.

H.3.1 Notification alternatives

1

LIA−1 requires at least the following two alternatives for handling of notifications:
setting indicators or trap-and-terminate. LIA−1 allows a third alternative: trap-and-
resume.

2

An implementation need only support a given notification alternative for the entire
program. An implementation may support the ability to switch between notification
alternatives during execution, but is not required to do so. An implementation can
provide separate selection for each kind of notification, but this is not required.

3

C allows an implementation to provide notification. C’s

SIGFPE

(for traps) and

FE_INVALID

,

FE_DIVBYZERO

,

FE_OVERFLOW

,

FE_UNDERFLOW

(for indicators)

can provide LIA−1 notification.

4

C’s signal handlers are compatible with LIA−1. Default handling of

SIGFPE

can

provide trap-and-terminate behavior, except for those LIA−1 operations implemented by
math library function calls. User-provided signal handlers for

SIGFPE

allow for trap-

and-resume behavior with the same constraint.

H.3.1.1 Indicators

1

C’s

<fenv.h>

status flags are compatible with the LIA−1 indicators.

2

The following mapping is for floating-point types:

undefined

FE_INVALID

,

FE_DIVBYZERO

floating_overflow

FE_OVERFLOW

underflow

FE_UNDERFLOW

3

The floating-point indicator interrogation and manipulation operations are:

set_indicators

feraiseexcept(i)

clear_indicators

feclearexcept(i)

test_indicators

fetestexcept(i)

current_indicators

fetestexcept(FE_ALL_EXCEPT)

where

i

is an expression of type

int

representing a subset of the LIA−1 indicators.

4

C allows an implementation to provide the following LIA−1 required behavior: at
program termination if any indicator is set the implementation shall send an unambiguous
§H.3.1.1 Language independent arithmetic

485

n

No input is consumed. The corresponding argument shall be a pointer to
signed integer into which is to be written the number of characters read from
the input stream so far by this call to the

fscanf

function. Execution of a

%n

directive does not increment the assignment count returned at the

completion of execution of the

fscanf

function. No argument is converted,

but one is consumed. If the conversion specification includes an assignment-
suppressing character or a field width, the behavior is undefined.

%

Matches a single

%

character; no conversion or assignment occurs. The

complete conversion specification shall be

%%

.

13

If a conversion specification is invalid, the behavior is undefined.

253)

14

The conversion specifiers

A

,

E

,

F

,

G

, and

X

are also valid and behave the same as,

respectively,

a

,

e

,

f

,

g

, and

x

.

15

Trailing white space (including new-line characters) is left unread unless matched by a
directive. The success of literal matches and suppressed assignments is not directly
determinable other than via the

%n

directive.

Returns

16

The

fscanf

function returns the value of the macro

EOF

if an input failure occurs

before any conversion. Otherwise, the function returns the number of input items
assigned, which can be fewer than provided for, or even zero, in the event of an early
matching failure.

17

EXAMPLE 1

The call:

#include <stdio.h>

/*

...

*/

int n, i; float x; char name[50];

n = fscanf(stdin, "%d%f%s", &i, &x, name);

with the input line:

25 54.32E-1 thompson

will assign to

n

the value 3, to

i

the value 25, to

x

the value 5.432, and to

name

the sequence

thompson\0

.

18

EXAMPLE 2

The call:

#include <stdio.h>

/*

...

*/

int i; float x; char name[50];

fscanf(stdin, "%2d%f%*d %[0123456789]", &i, &x, name);

with input:

253) See ‘‘future library directions’’ (7.26.9).

§7.19.6.2 Library

287

56789 0123 56a72

will assign to

i

the value 56 and to

x

the value 789.0, will skip

0123

, and will assign to

name

the

sequence

56\0

. The next character read from the input stream will be

a

.

19

EXAMPLE 3

To accept repeatedly from

stdin

a quantity, a unit of measure, and an item name:

#include <stdio.h>

/*

...

*/

int count; float quant; char units[21], item[21];

do {

count = fscanf(stdin, "%f%20s of %20s", &quant, units, item);

fscanf(stdin,"%*[^\n]");

} while (!feof(stdin) && !ferror(stdin));

20

If the

stdin

stream contains the following lines:

2 quarts of oil

-12.8degrees Celsius

lots of luck

10.0LBS of

dirt

100ergs of energy

the execution of the above example will be analogous to the following assignments:

quant = 2; strcpy(units, "quarts"); strcpy(item, "oil");

count = 3;

quant = -12.8; strcpy(units, "degrees");

count = 2; // "C"

fails to match

"o"

count = 0; // "l"

fails to match

"%f"

quant = 10.0; strcpy(units, "LBS"); strcpy(item, "dirt");

count = 3;

count = 0; // "100e"

fails to match

"%f"

count = EOF;

21

EXAMPLE 4

In:

#include <stdio.h>

/*

...

*/

int d1, d2, n1, n2, i;

i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);

the value 123 is assigned to

d1

and the value 3 to

n1

. Because

%n

can never get an input failure the value

of 3 is also assigned to

n2

. The value of

d2

is not affected. The value 1 is assigned to

i

.

22

EXAMPLE 5

In these examples, multibyte characters do have a state-dependent encoding, and the

members of the extended character set that consist of more than one byte each consist of exactly two bytes,
the first of which is denoted here by a

and the second by an uppercase letter, but are only recognized as

such when in the alternate shift state. The shift sequences are denoted by

and

, in which the first causes

entry into the alternate shift state.

23

After the call:

288 Library

§7.19.6.2

#include <stdio.h>

/*

...

*/

char str[50];

fscanf(stdin, "a%s", str);

with the input line:

a

X Y

bc

str

will contain

X Y

\0

assuming that none of the bytes of the shift sequences (or of the multibyte

characters, in the more general case) appears to be a single-byte white-space character.

24

In contrast, after the call:

#include <stdio.h>

#include <stddef.h>

/*

...

*/

wchar_t wstr[50];

fscanf(stdin, "a%ls", wstr);

with the same input line,

wstr

will contain the two wide characters that correspond to

X

and

Y

and a

terminating null wide character.

25

However, the call:

#include <stdio.h>

#include <stddef.h>

/*

...

*/

wchar_t wstr[50];

fscanf(stdin, "a

X

%ls", wstr);

with the same input line will return zero due to a matching failure against the

sequence in the format

string.

26

Assuming that the first byte of the multibyte character

X

is the same as the first byte of the multibyte

character

Y

, after the call:

#include <stdio.h>

#include <stddef.h>

/*

...

*/

wchar_t wstr[50];

fscanf(stdin, "a

Y

%ls", wstr);

with the same input line, zero will again be returned, but

stdin

will be left with a partially consumed

multibyte character.

Forward references: the

strtod

,

strtof

, and

strtold

functions (7.20.1.3), the

strtol

,

strtoll

,

strtoul

, and

strtoull

functions (7.20.1.4), conversion state

(7.24.6), the

wcrtomb

function (7.24.6.3.3).

§7.19.6.2 Library

289

7.19.6.3 The

printf

function

Synopsis

1

#include <stdio.h>

int printf(const char * restrict format, ...);

Description

2

The

printf

function is equivalent to

fprintf

with the argument

stdout

interposed

before the arguments to

printf

.

Returns

3

The

printf

function returns the number of characters transmitted, or a negative value if

an output or encoding error occurred.

7.19.6.4 The

scanf

function

Synopsis

1

#include <stdio.h>

int scanf(const char * restrict format, ...);

Description

2

The

scanf

function is equivalent to

fscanf

with the argument

stdin

interposed

before the arguments to

scanf

.

Returns

3

The

scanf

function returns the value of the macro

EOF

if an input failure occurs before

any conversion. Otherwise, the

scanf

function returns the number of input items

assigned, which can be fewer than provided for, or even zero, in the event of an early
matching failure.

7.19.6.5 The

snprintf

function

Synopsis

1

#include <stdio.h>

int snprintf(char * restrict s, size_t n,

const char * restrict format, ...);

Description

2

The

snprintf

function is equivalent to

fprintf

, except that the output is written into

an array (specified by argument

s

) rather than to a stream. If

n

is zero, nothing is written,

and

s

may be a null pointer. Otherwise, output characters beyond the

n-1

st are

discarded rather than being written to the array, and a null character is written at the end
of the characters actually written into the array. If copying takes place between objects
that overlap, the behavior is undefined.

290 Library

§7.19.6.5

Returns

3

The

snprintf

function returns the number of characters that would have been written

had

n

been sufficiently large, not counting the terminating null character, or a neg ative

value if an encoding error occurred.

Thus, the null-terminated output has been

completely written if and only if the returned value is nonnegative and less than

n

.

7.19.6.6 The

sprintf

function

Synopsis

1

#include <stdio.h>

int sprintf(char * restrict s,

const char * restrict format, ...);

Description

2

The

sprintf

function is equivalent to

fprintf

, except that the output is written into

an array (specified by the argument

s

) rather than to a stream. A null character is written

at the end of the characters written; it is not counted as part of the returned value. If
copying takes place between objects that overlap, the behavior is undefined.

Returns

3

The

sprintf

function returns the number of characters written in the array, not

counting the terminating null character, or a neg ative value if an encoding error occurred.

7.19.6.7 The

sscanf

function

Synopsis

1

#include <stdio.h>

int sscanf(const char * restrict s,

const char * restrict format, ...);

Description

2

The

sscanf

function is equivalent to

fscanf

, except that input is obtained from a

string (specified by the argument

s

) rather than from a stream. Reaching the end of the

string is equivalent to encountering end-of-file for the

fscanf

function. If copying

takes place between objects that overlap, the behavior is undefined.

Returns

3

The

sscanf

function returns the value of the macro

EOF

if an input failure occurs

before any conversion. Otherwise, the

sscanf

function returns the number of input

items assigned, which can be fewer than provided for, or even zero, in the event of an
early matching failure.

§7.19.6.7 Library

291

7.19.6.8 The

vfprintf

function

Synopsis

1

#include <stdarg.h>

#include <stdio.h>

int vfprintf(FILE * restrict stream,

const char * restrict format,

va_list arg);

Description

2

The

vfprintf

function is equivalent to

fprintf

, with the variable argument list

replaced by

arg

, which shall have been initialized by the

va_start

macro (and

possibly subsequent

va_arg

calls). The

vfprintf

function does not invoke the

va_end

macro.

254)

Returns

3

The

vfprintf

function returns the number of characters transmitted, or a negative

value if an output or encoding error occurred.

4

EXAMPLE The following shows the use of the

vfprintf

function in a general error-reporting routine.

#include <stdarg.h>

#include <stdio.h>

void error(char *function_name, char *format, ...)

{

va_list args;

va_start(args, format);

//

print out name of function causing error

fprintf(stderr, "ERROR in %s: ", function_name);

//

print out remainder of message

vfprintf(stderr, format, args);

va_end(args);

}

254) As the functions

vfprintf

,

vfscanf

,

vprintf

,

vscanf

,

vsnprintf

,

vsprintf

, and

vsscanf

invoke the

va_arg

macro, the value of

arg

after the return is indeterminate.

292 Library

§7.19.6.8

7.19.6.9 The

vfscanf

function

Synopsis

1

#include <stdarg.h>

#include <stdio.h>

int vfscanf(FILE * restrict stream,

const char * restrict format,

va_list arg);

Description

2

The

vfscanf

function is equivalent to

fscanf

, with the variable argument list

replaced by

arg

, which shall have been initialized by the

va_start

macro (and

possibly subsequent

va_arg

calls). The

vfscanf

function does not invoke the

va_end

macro.

254)

Returns

3

The

vfscanf

function returns the value of the macro

EOF

if an input failure occurs

before any conversion. Otherwise, the

vfscanf

function returns the number of input

items assigned, which can be fewer than provided for, or even zero, in the event of an
early matching failure.

7.19.6.10 The

vprintf

function

Synopsis

1

#include <stdarg.h>

#include <stdio.h>

int vprintf(const char * restrict format,

va_list arg);

Description

2

The

vprintf

function is equivalent to

printf

, with the variable argument list

replaced by

arg

, which shall have been initialized by the

va_start

macro (and

possibly subsequent

va_arg

calls). The

vprintf

function does not invoke the

va_end

macro.

254)

Returns

3

The

vprintf

function returns the number of characters transmitted, or a negative value

if an output or encoding error occurred.

§7.19.6.10 Library

293

7.19.6.11 The

vscanf

function

Synopsis

1

#include <stdarg.h>

#include <stdio.h>

int vscanf(const char * restrict format,

va_list arg);

Description

2

The

vscanf

function is equivalent to

scanf

, with the variable argument list replaced

by

arg

, which shall have been initialized by the

va_start

macro (and possibly

subsequent

va_arg

calls). The

vscanf

function does not invoke the

va_end

macro.

254)

Returns

3

The

vscanf

function returns the value of the macro

EOF

if an input failure occurs

before any conversion. Otherwise, the

vscanf

function returns the number of input

items assigned, which can be fewer than provided for, or even zero, in the event of an
early matching failure.

7.19.6.12 The

vsnprintf

function

Synopsis

1

#include <stdarg.h>

#include <stdio.h>

int vsnprintf(char * restrict s, size_t n,

const char * restrict format,

va_list arg);

Description

2

The

vsnprintf

function is equivalent to

snprintf

, with the variable argument list

replaced by

arg

, which shall have been initialized by the

va_start

macro (and

possibly subsequent

va_arg

calls). The

vsnprintf

function does not invoke the

va_end

macro.

254)

If copying takes place between objects that overlap, the behavior is

undefined.

Returns

3

The

vsnprintf

function returns the number of characters that would have been written

had

n

been sufficiently large, not counting the terminating null character, or a neg ative

value if an encoding error occurred.

Thus, the null-terminated output has been

completely written if and only if the returned value is nonnegative and less than

n

.

294 Library

§7.19.6.12

7.19.6.13 The

vsprintf

function

Synopsis

1

#include <stdarg.h>

#include <stdio.h>

int vsprintf(char * restrict s,

const char * restrict format,

va_list arg);

Description

2

The

vsprintf

function is equivalent to

sprintf

, with the variable argument list

replaced by

arg

, which shall have been initialized by the

va_start

macro (and

possibly subsequent

va_arg

calls). The

vsprintf

function does not invoke the

va_end

macro.

254)

If copying takes place between objects that overlap, the behavior is

undefined.

Returns

3

The

vsprintf

function returns the number of characters written in the array, not

counting the terminating null character, or a neg ative value if an encoding error occurred.

7.19.6.14 The

vsscanf

function

Synopsis

1

#include <stdarg.h>

#include <stdio.h>

int vsscanf(const char * restrict s,

const char * restrict format,

va_list arg);

Description

2

The

vsscanf

function is equivalent to

sscanf

, with the variable argument list

replaced by

arg

, which shall have been initialized by the

va_start

macro (and

possibly subsequent

va_arg

calls). The

vsscanf

function does not invoke the

va_end

macro.

254)

Returns

3

The

vsscanf

function returns the value of the macro

EOF

if an input failure occurs

before any conversion. Otherwise, the

vsscanf

function returns the number of input

items assigned, which can be fewer than provided for, or even zero, in the event of an
early matching failure.

§7.19.6.14 Library

295

7.19.7 Character input/output functions

7.19.7.1 The

fgetc

function

Synopsis

1

#include <stdio.h>

int fgetc(FILE *stream);

Description

2

If the end-of-file indicator for the input stream pointed to by

stream

is not set and a

next character is present, the

fgetc

function obtains that character as an

unsigned

char

converted to an

int

and advances the associated file position indicator for the

stream (if defined).

Returns

3

If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-
of-file indicator for the stream is set and the

fgetc

function returns

EOF

. Otherwise, the

fgetc

function returns the next character from the input stream pointed to by

stream

.

If a read error occurs, the error indicator for the stream is set and the

fgetc

function

returns

EOF

.

255)

7.19.7.2 The

fgets

function

Synopsis

1

#include <stdio.h>

char *fgets(char * restrict s, int n,

FILE * restrict stream);

Description

2

The

fgets

function reads at most one less than the number of characters specified by

n

from the stream pointed to by

stream

into the array pointed to by

s

. No additional

characters are read after a new-line character (which is retained) or after end-of-file. A
null character is written immediately after the last character read into the array.

Returns

3

The

fgets

function returns

s

if successful. If end-of-file is encountered and no

characters have been read into the array, the contents of the array remain unchanged and a
null pointer is returned. If a read error occurs during the operation, the array contents are
indeterminate and a null pointer is returned.

255) An end-of-file and a read error can be distinguished by use of the

feof

and

ferror

functions.

296 Library

§7.19.7.2

7.19.7.3 The

fputc

function

Synopsis

1

#include <stdio.h>

int fputc(int c, FILE *stream);

Description

2

The

fputc

function writes the character specified by

c

(converted to an

unsigned

char

) to the output stream pointed to by

stream

, at the position indicated by the

associated file position indicator for the stream (if defined), and advances the indicator
appropriately. If the file cannot support positioning requests, or if the stream was opened
with append mode, the character is appended to the output stream.

Returns

3

The

fputc

function returns the character written. If a write error occurs, the error

indicator for the stream is set and

fputc

returns

EOF

.

7.19.7.4 The

fputs

function

Synopsis

1

#include <stdio.h>

int fputs(const char * restrict s,

FILE * restrict stream);

Description

2

The

fputs

function writes the string pointed to by

s

to the stream pointed to by

stream

. The terminating null character is not written.

Returns

3

The

fputs

function returns

EOF

if a write error occurs; otherwise it returns a

nonnegative value.

7.19.7.5 The

getc

function

Synopsis

1

#include <stdio.h>

int getc(FILE *stream);

Description

2

The

getc

function is equivalent to

fgetc

, except that if it is implemented as a macro, it

may evaluate

stream

more than once, so the argument should never be an expression

with side effects.

§7.19.7.5 Library

297

Returns

3

The

getc

function returns the next character from the input stream pointed to by

stream

. If the stream is at end-of-file, the end-of-file indicator for the stream is set and

getc

returns

EOF

. If a read error occurs, the error indicator for the stream is set and

getc

returns

EOF

.

7.19.7.6 The

getchar

function

Synopsis

1

#include <stdio.h>

int getchar(void);

Description

2

The

getchar

function is equivalent to

getc

with the argument

stdin

.

Returns

3

The

getchar

function returns the next character from the input stream pointed to by

stdin

. If the stream is at end-of-file, the end-of-file indicator for the stream is set and

getchar

returns

EOF

. If a read error occurs, the error indicator for the stream is set and

getchar

returns

EOF

.

7.19.7.7 The

gets

function

Synopsis

1

#include <stdio.h>

char *gets(char *s);

Description

2

The

gets

function reads characters from the input stream pointed to by

stdin

, into the

array pointed to by

s

, until end-of-file is encountered or a new-line character is read.

Any new-line character is discarded, and a null character is written immediately after the
last character read into the array.

Returns

3

The

gets

function returns

s

if successful. If end-of-file is encountered and no

characters have been read into the array, the contents of the array remain unchanged and a
null pointer is returned. If a read error occurs during the operation, the array contents are
indeterminate and a null pointer is returned.

Forward references: future library directions (7.26.9).

298 Library

§7.19.7.7

7.19.7.8 The

putc

function

Synopsis

1

#include <stdio.h>

int putc(int c, FILE *stream);

Description

2

The

putc

function is equivalent to

fputc

, except that if it is implemented as a macro, it

may evaluate

stream

more than once, so that argument should never be an expression

with side effects.

Returns

3

The

putc

function returns the character written. If a write error occurs, the error

indicator for the stream is set and

putc

returns

EOF

.

7.19.7.9 The

putchar

function

Synopsis

1

#include <stdio.h>

int putchar(int c);

Description

2

The

putchar

function is equivalent to

putc

with the second argument

stdout

.

Returns

3

The

putchar

function returns the character written. If a write error occurs, the error

indicator for the stream is set and

putchar

returns

EOF

.

7.19.7.10 The

puts

function

Synopsis

1

#include <stdio.h>

int puts(const char *s);

Description

2

The

puts

function writes the string pointed to by

s

to the stream pointed to by

stdout

,

and appends a new-line character to the output. The terminating null character is not
written.

Returns

3

The

puts

function returns

EOF

if a write error occurs; otherwise it returns a nonnegative

value.

§7.19.7.10 Library

299

 

 

 

 

 

 

 

Content      ..     12      13      14      15     ..