{"id":756,"date":"2016-05-09T22:44:36","date_gmt":"2016-05-09T21:44:36","guid":{"rendered":"http:\/\/numbercrunch.de\/blog\/?p=756"},"modified":"2023-01-10T23:38:10","modified_gmt":"2023-01-10T22:38:10","slug":"c1114-for-scientific-computing-vi","status":"publish","type":"post","link":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/","title":{"rendered":"C++11\/14 for scientific computing VI"},"content":{"rendered":"<h1>Floating-point exceptions<\/h1>\n<p style=\"text-align: justify;\">During a numerical calculation various kinds of run-time errors may occur. In C++, such an error may be indicated via floating-point exceptions or via the (global but thread-local) variable <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/error\/errno\" target=\"_blank\" rel=\"noopener\">errno<\/a>. Floating-point exceptions are completely unrelated to C++ exceptions. When an floating-point exception is raised by an erroneous operation,<var><\/var> the exception is simply noted in the floating-point status word, and the program continues. The operation produces a default value, which depends on the exception (see the table below). C++11 introduces with the new header file <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/header\/cfenv\" target=\"_blank\" rel=\"noopener\"><code>cfenv<\/code><\/a> functions to check and to manipulate the floating-point environment and the floating-point status flags. In this way, a program can find out which exceptions have been raised. The value of the macro <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/numeric\/math\/math_errhandling\" target=\"_blank\" rel=\"noopener\"><code>math_errhandling<\/code><\/a> indicates the type of error handling that is performed by the floating-point operators and functions.<\/p>\n<p style=\"text-align: justify;\">The IEEE\u00a0754 standard defines five floating-point exceptions:<\/p>\n<ul>\n<li><em>Invalid operation<\/em>, e.g., square root of a negative number, which returns quiet NaN by default.<\/li>\n<li><em>Division by zero<\/em>, i.e., an operation on finite operands gives an exact infinite result, e.g., $1\/0$ or $\\log(0)$), which returns $\\pm\\infty$ by default.<\/li>\n<li><em>Overflow<\/em>, i.e., a result that is too large to be represented correctly by a floating-point number, which returns $\\pm\\infty$ by default (for round-to-nearest mode).<\/li>\n<li><em>Underflow<\/em>, i.e., a result that is very small (outside the normal range) and is inexact, which returns a denormalized value by default.<\/li>\n<li><em>Inexact<\/em>, which returns correctly rounded result by default.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">The following program raises various floating-point exceptions and illustrates how to detect them. First, one has to tell the compiler that the floating-point environment will be investigated via the <code>#pragma STDC FENV_ACCESS ON<\/code>, which forces the compiler to prevent some optimizations, which may invalidate the floating-point status. The function <code>feclearexcept<\/code> clears the specified floating-point status flags, while <code>fetestexcept<\/code> determines which of the specified floating-point status flags are set. Floating-point exceptions are represented by <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/numeric\/fenv\/FE_exceptions\" target=\"_blank\" rel=\"noopener\">macro constants<\/a> <code>FE_INVALID<\/code> etc. The program&#8217;s expected output is:<\/p>\n<pre>MATH_ERRNO is set\nMATH_ERREXCEPT is set\n\n1.0\/0.0 = inf\nERROR: division by zero\n\n2^2000 = inf\nERROR: numerical overflow\n\n1\/2^2000 = 0\nERROR: numerical underflow\n\nsqrt(-1) = -nan\nERROR: invalid result\n<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#pragma STDC FENV_ACCESS ON\n\n#include &lt;cstdlib&gt;\n#include &lt;iostream&gt;\n#include &lt;cfenv&gt;\n#include &lt;cmath&gt;\n\nvoid test_fp_exceptions() {\n  bool error=false;\n  if (std::fetestexcept(FE_DIVBYZERO)) {\n    error=true;\n    std::cerr &lt;&lt; \"ERROR: division by zero\\n\";\n  }\n  if (std::fetestexcept(FE_OVERFLOW)) {\n    error=true;\n    std::cerr &lt;&lt; \"ERROR: numerical overflow\\n\";\n  }\n  if (std::fetestexcept(FE_UNDERFLOW)) {\n    error=true; \n    std::cerr &lt;&lt; \"ERROR: numerical underflow\\n\";\n  }\n  if (std::fetestexcept(FE_INVALID)) {\n    error=true;\n    std::cerr &lt;&lt; \"ERROR: invalid result\\n\";\n  }\n  if (not error)\n    std::cerr &lt;&lt; \"no error\\n\";\n  std::feclearexcept(FE_ALL_EXCEPT);\n  std::cerr &lt;&lt; '\\n';\n}\n\nint main() {\n  double zero=0.0;\n\n  std::cout &lt;&lt; \"MATH_ERRNO is \"\n        &lt;&lt; (math_errhandling &amp; MATH_ERRNO ? \"set\" : \"not set\") &lt;&lt; '\\n'\n        &lt;&lt; \"MATH_ERREXCEPT is \"\n        &lt;&lt; (math_errhandling &amp; MATH_ERREXCEPT ? \"set\" : \"not set\") &lt;&lt; '\\n'\n        &lt;&lt; '\\n';\n\n  std::feclearexcept(FE_ALL_EXCEPT);\n\n  std::cout &lt;&lt;  \"1.0\/0.0 = \" &lt;&lt; 1.0\/zero &lt;&lt; '\\n';\n  test_fp_exceptions();\n\n  std::cout &lt;&lt; \"2^2000 = \" &lt;&lt; std::pow(2., 2000) &lt;&lt; '\\n';\n  test_fp_exceptions();\n\n  std::cout &lt;&lt; \"1\/2^2000 = \" &lt;&lt; std::pow(2., -2000) &lt;&lt; '\\n';\n  test_fp_exceptions();\n\n  std::cout &lt;&lt; \"sqrt(-1) = \" &lt;&lt; std::sqrt(-1.) &lt;&lt; '\\n';\n  test_fp_exceptions();\n\n  return EXIT_SUCCESS;\n}\n<\/pre>\n<p style=\"text-align: justify;\">Testing\u00a0 explicitly for floating-point exceptions can become tedious. The GNU C library provides the functions <code>feenableexcept<\/code>, <code>fedisableexcept<\/code>, and <code>fegetexcept<\/code>, to enable (and disable) traps for floating-point exceptions. This means, a floating-point exception is turned into a signal, which may be caught by a signal handler, as shown by the following program, which requires the GNU C++ compiler to compile.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#pragma STDC FENV_ACCESS ON\n#include&lt;cstdlib&gt;\n#include&lt;iostream&gt;\n#include&lt;cfenv&gt;\n#include&lt;fenv.h&gt;\n#include&lt;signal.h&gt;\n\nvoid floating_point_handler(int signal, siginfo_t *sip, void *uap) {\n  std::cerr &lt;&lt; \"floating point error at \" &lt;&lt; sip-&gt;si_addr &lt;&lt; \" : \";\n  int code=sip-&gt;si_code;\n  if (code==FPE_FLTDIV)\n    std::cerr &lt;&lt; \"division by zero\\n\";\n  if (code==FPE_FLTUND)\n    std::cerr &lt;&lt; \"underflow\\n\";\n  if (code==FPE_FLTOVF)\n    std::cerr &lt;&lt; \"overflow\\n\";\n  if (code==FPE_FLTINV)\n    std::cerr &lt;&lt; \"invalid result\\n\";\n  std::abort();\n}\n\nint main() {\n  std::feclearexcept(FE_ALL_EXCEPT);\n  feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);\n  struct sigaction act;\n  act.sa_sigaction=floating_point_handler;\n  act.sa_flags=SA_SIGINFO;\n  sigaction(SIGFPE, &amp;act, NULL);\n\n  double zero=0.0;\n  double one=1.0;\n\n  std::cout &lt;&lt; \"1.0\/1.0 = \" &lt;&lt; one\/one &lt;&lt; '\\n';\n  std::cout &lt;&lt; \"1.0\/0.0 = \" &lt;&lt; one\/zero &lt;&lt; '\\n';\n  std::cout &lt;&lt; \"1.0\/1.0 = \" &lt;&lt; one\/one &lt;&lt; '\\n';\n\n  return EXIT_SUCCESS;\n}\n<\/pre>\n<p style=\"text-align: justify;\">Usually a signal handler will not do much more than emitting an error message, performing some clean-up work, and aborting the program, in particular, when the floating-point error is fatal, e.g., division by zero. Furthermore, when the program exits the signal handler, the floating point-exception is raised again. Consequently, the signal handler is called again, which results into an infinite loop of calls to the signal handler. A solution to this problem is to employ non-local jumps via <code>sigsetjmp<\/code> and <code>siglongjmp<\/code> to implement an exception mechanism, as illustrated below.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#pragma STDC FENV_ACCESS ON\n\n#include&lt;cstdlib&gt;\n#include&lt;iostream&gt;\n#include&lt;cfenv&gt;\n#include&lt;fenv.h&gt;\n#include&lt;signal.h&gt;\n#include&lt;setjmp.h&gt;\n\nstatic sigjmp_buf jmpbuf;\n\nvoid floating_point_handler(int signal, siginfo_t *sip, void *uap) {\n  std::cerr &lt;&lt; \"floating point error at \" &lt;&lt; sip-&gt;si_addr &lt;&lt; \" : \";\n  int code=sip-&gt;si_code;\n  if (code==FPE_FLTDIV)\n    std::cerr &lt;&lt; \"division by zero\\n\";\n  if (code==FPE_FLTUND)\n    std::cerr &lt;&lt; \"underflow\\n\";\n  if (code==FPE_FLTOVF)\n    std::cerr &lt;&lt; \"overflow\\n\";\n  if (code==FPE_FLTINV)\n    std::cerr &lt;&lt; \"invalid result\\n\";\n  feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);\n  siglongjmp(jmpbuf, 1);\n}\n\nint main() {\n  std::feclearexcept(FE_ALL_EXCEPT);\n  feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);\n  struct sigaction act;\n  act.sa_sigaction=floating_point_handler;\n  act.sa_flags=SA_SIGINFO;\n  sigaction(SIGFPE, &amp;act, NULL);\n\n  double zero=0.0;\n  double one=1.0;\n\n  if (sigsetjmp(jmpbuf, 1)==0) {  \/\/ try\n    std::cout &lt;&lt; \"1.0\/1.0 = \" &lt;&lt; one\/one &lt;&lt; '\\n';\n    std::cout &lt;&lt; \"1.0\/0.0 = \" &lt;&lt; one\/zero &lt;&lt; '\\n';\n    std::cout &lt;&lt; \"1.0\/1.0 = \" &lt;&lt; one\/one &lt;&lt; '\\n';\n  } else {  \/\/ catch\n    std::cerr &lt;&lt; \"some error occurred\\n\";\n  }\n  return EXIT_SUCCESS;\n}\n<\/pre>\n<p style=\"text-align: justify;\">Employing the techniques for catching floating-point exceptions as shown above, erroneous numerical calculations become easy to detect and make it possible to deal with them accordingly.<\/p>\n<p style=\"text-align: justify;\">\n","protected":false},"excerpt":{"rendered":"<p>Floating-point exceptions During a numerical calculation various kinds of run-time errors may occur. In C++, such an error may be indicated via floating-point exceptions or via the (global but thread-local) variable errno. Floating-point exceptions are completely unrelated to C++ exceptions. When an floating-point exception is raised by an erroneous operation, the exception is simply noted&hellip; <a href=\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">C++11\/14 for scientific computing VI<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16],"tags":[],"class_list":["post-756","post","type-post","status-publish","format-standard","hentry","category-c"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>C++11\/14 for scientific computing VI - Number Crunch<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"C++11\/14 for scientific computing VI - Number Crunch\" \/>\n<meta property=\"og:description\" content=\"Floating-point exceptions During a numerical calculation various kinds of run-time errors may occur. In C++, such an error may be indicated via floating-point exceptions or via the (global but thread-local) variable errno. Floating-point exceptions are completely unrelated to C++ exceptions. When an floating-point exception is raised by an erroneous operation, the exception is simply noted&hellip; Continue reading C++11\/14 for scientific computing VI\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\" \/>\n<meta property=\"og:site_name\" content=\"Number Crunch\" \/>\n<meta property=\"article:published_time\" content=\"2016-05-09T21:44:36+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-10T22:38:10+00:00\" \/>\n<meta name=\"author\" content=\"Heiko Bauke\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Heiko Bauke\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\"},\"author\":{\"name\":\"Heiko Bauke\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"headline\":\"C++11\/14 for scientific computing VI\",\"datePublished\":\"2016-05-09T21:44:36+00:00\",\"dateModified\":\"2023-01-10T22:38:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\"},\"wordCount\":489,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"articleSection\":[\"C++\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\",\"url\":\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\",\"name\":\"C++11\/14 for scientific computing VI - Number Crunch\",\"isPartOf\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#website\"},\"datePublished\":\"2016-05-09T21:44:36+00:00\",\"dateModified\":\"2023-01-10T22:38:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.numbercrunch.de\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"C++11\/14 for scientific computing VI\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#website\",\"url\":\"https:\/\/www.numbercrunch.de\/blog\/\",\"name\":\"Number Crunch\",\"description\":\"A computational science blog.\",\"publisher\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.numbercrunch.de\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\",\"name\":\"Heiko Bauke\",\"logo\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"C++11\/14 for scientific computing VI - Number Crunch","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/","og_locale":"en_US","og_type":"article","og_title":"C++11\/14 for scientific computing VI - Number Crunch","og_description":"Floating-point exceptions During a numerical calculation various kinds of run-time errors may occur. In C++, such an error may be indicated via floating-point exceptions or via the (global but thread-local) variable errno. Floating-point exceptions are completely unrelated to C++ exceptions. When an floating-point exception is raised by an erroneous operation, the exception is simply noted&hellip; Continue reading C++11\/14 for scientific computing VI","og_url":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/","og_site_name":"Number Crunch","article_published_time":"2016-05-09T21:44:36+00:00","article_modified_time":"2023-01-10T22:38:10+00:00","author":"Heiko Bauke","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Heiko Bauke","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#article","isPartOf":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/"},"author":{"name":"Heiko Bauke","@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"headline":"C++11\/14 for scientific computing VI","datePublished":"2016-05-09T21:44:36+00:00","dateModified":"2023-01-10T22:38:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/"},"wordCount":489,"commentCount":0,"publisher":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"articleSection":["C++"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/","url":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/","name":"C++11\/14 for scientific computing VI - Number Crunch","isPartOf":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#website"},"datePublished":"2016-05-09T21:44:36+00:00","dateModified":"2023-01-10T22:38:10+00:00","breadcrumb":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.numbercrunch.de\/blog\/2016\/05\/c1114-for-scientific-computing-vi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.numbercrunch.de\/blog\/"},{"@type":"ListItem","position":2,"name":"C++11\/14 for scientific computing VI"}]},{"@type":"WebSite","@id":"https:\/\/www.numbercrunch.de\/blog\/#website","url":"https:\/\/www.numbercrunch.de\/blog\/","name":"Number Crunch","description":"A computational science blog.","publisher":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.numbercrunch.de\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413","name":"Heiko Bauke","logo":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/756"}],"collection":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/comments?post=756"}],"version-history":[{"count":20,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/756\/revisions"}],"predecessor-version":[{"id":949,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/756\/revisions\/949"}],"wp:attachment":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/media?parent=756"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/categories?post=756"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/tags?post=756"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}