, :
, , . :
double mul(double a, double b, int *status) {
#pragma STDC FENV_ACCESS ON
fexcept_t flags;
int sv_status, f_status = -1;
double resul;
sv_status = fegetexceptflag(&flags, FE_ALL_EXCEPT) != 0;
if (sv_status == 0) {
f_status = feclearexcept(FE_ALL_EXCEPT);
}
resul = a * b;
if (f_status == 0) {
*status = fetestexcept(FE_ALL_EXCEPT);
}
if (sv_status == 0) {
fesetexceptflag(&flags, FE_ALL_EXCEPT);
}
return resul;
}
:
int main ()
{
double d2, d3, d4;
int status;
double d = 1e100;
feraiseexcept(FE_OVERFLOW | FE_INEXACT);
status = fetestexcept(FE_ALL_EXCEPT);
printf("initial status : %x\n", status);
d2 = mul(3., 4., &status);
printf("resul 3 * 4 : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d, d, &status);
printf("resul d * d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d2, d, &status);
printf("resul d *d *d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d2, d, &status);
printf("resul d *d *d*d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d2, d, &status);
printf("resul d *d *d*d*d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
return 0;
}
:
initial status : 28
resul 3 * 4 : 12 - status 0 (28)
resul d * d : 1e+200 - status 20 (28)
resul d *d *d : 1e+300 - status 20 (28)
resul d *d *d*d : inf - status 28 (28)
resul d *d *d*d*d : inf - status 0 (28)
, mul:
, C, , C99.
.
: ISO/IEC 9899: 201x (ISO C11)
Nota: Clang ( ) , STDS FENV_ACCESS,