From b3e9e62599532050fc776c5e8f076915b56c2235 Mon Sep 17 00:00:00 2001 From: David Faulkner Date: Fri, 7 Aug 2026 23:40:47 -0500 Subject: Import official C23 code examples for Modern C (Jens Gustedt, 2024) - Add official C source files, Makefile, c23-fallback.h, and LICENSE - Update README.md with study mirror notice --- fp_except.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 fp_except.c (limited to 'fp_except.c') 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 +#include +#include +#ifndef INFINITY +#include +#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(""); + } +} -- cgit v1.2.3