diff options
| author | David Faulkner <[email protected]> | 2026-08-07 23:40:47 -0500 |
|---|---|---|
| committer | David Faulkner <[email protected]> | 2026-08-07 23:40:47 -0500 |
| commit | b3e9e62599532050fc776c5e8f076915b56c2235 (patch) | |
| tree | af252346106a61b18cc6fc6fdbd32e962d096f1c /fp_except.c | |
Import official C23 code examples for Modern C (Jens Gustedt, 2024)HEADupstream-importmain
- Add official C source files, Makefile, c23-fallback.h, and LICENSE
- Update README.md with study mirror notice
Diffstat (limited to 'fp_except.c')
| -rw-r--r-- | fp_except.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/fp_except.c b/fp_except.c new file mode 100644 index 0000000..5dc63ec --- /dev/null +++ b/fp_except.c @@ -0,0 +1,88 @@ +#include "c23-fallback.h" +#include <stdio.h> +#include <fenv.h> +#include <float.h> +#ifndef INFINITY +#include <math.h> +#endif + +#if !defined(__STDC_IEC_559__) && !defined(__STDC_IEC_60559_BFP__) && !FE_ALL_EXCEPT +#error "floating-point arithmetic is too weird" +#endif + +static_assert(FE_ALL_EXCEPT, "floating point exceptions are not supported"); + +#ifdef FENV_OFF +#warning "switching FENV_ACCESS off" +#pragma STDC FENV_ACCESS OFF +#else +#pragma STDC FENV_ACCESS ON +#endif + +bool const has_inf = +#ifdef INFINITY + (1.0/0.0 == INFINITY) +#else + false +#endif + ; + +int excepts[] = { +#ifdef FE_DIVBYZERO + FE_DIVBYZERO, +#endif +#ifdef FE_INEXACT + FE_INEXACT, +#endif +#ifdef FE_INVALID + FE_INVALID, +#endif +#ifdef FE_OVERFLOW + FE_OVERFLOW, +#endif +#ifdef FE_UNDERFLOW + FE_UNDERFLOW, +#endif +}; + +void printexcept(void) { + char const* name[] = { +#ifdef FE_DIVBYZERO + "divbyzero", +#endif +#ifdef FE_INEXACT + "inexact", +#endif +#ifdef FE_INVALID + "invalid", +#endif +#ifdef FE_OVERFLOW + "overflow", +#endif +#ifdef FE_UNDERFLOW + "underflow", +#endif + }; + int except = fetestexcept(FE_ALL_EXCEPT); + if (except) { + printf("["); + for (unsigned j = 0; except; except &= ~excepts[j], ++j) + if (excepts[j] & except) + printf("%s ", name[j]); + printf("]"); + } +} + +int main (int argc, char* argv[static argc+1]) { + printf("division by zero is %sequal to INFINITY\n", has_inf ? "" : "un"); + for (unsigned i = 1; i < argc; i++) { + feclearexcept(FE_ALL_EXCEPT); + double x = strtod(argv[i], nullptr); + printf("%g ", x); + printexcept(); + feclearexcept(FE_ALL_EXCEPT); + printf(": %g ", 1.0/x); + printexcept(); + puts(""); + } +} |
