问题标签 [fenv]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 如何在 C 中引发不同的浮点异常?
我有兴趣提出浮点异常,如Division by zero
, Overflow
,Underflow
等。
我认为,如果我们可以在浮点异常发生时更改陷阱的默认行为,我想做的事情是可能的。
我在fenv.h
. 首先,我使用启用中断
feenableexcept
,然后使用feraiseexcept
.
终端中显示的消息是
Floating point exception (core dumped)
而不是这个,我想要这个表格的信息
Overflow
我也尝试过处理 SIGFPE。由于对于每个浮点异常,都会引发相同的信号 SIGPE,因此它无助于区分不同的信号原因。Stack overflow 上有一个类似的问题,但没有任何令人满意的答案。
我们可以使用 fetestexcept(FE_OVERFLOW) ,但必须在每次浮点运算后明确写入以检查溢出。
注意:我编译我的程序使用
gcc test_float -lm
编辑:
我尝试捕捉 SIGFPE 并编写了这个程序
它没有按我的预期工作。输出是
i am in catch_fpe
它也应该显示DIVBYZERO
。
c++ - C++设置浮点异常环境
我正在努力尝试以便携式方式设置 std::fenv 。
基于这个cppreference 页面,似乎fesetexceptflag(const std::fexcept_t*,int)
应该可以帮助我解决问题。另一方面,我发现 GNU 也提供了这个feenableexcept(int)
功能。我的理解是feenablexcept
GNU 特定的,虽然我很可能总是可以访问 GNU 的东西,但我希望只使用 std 的东西,也就是说,坚持使用fesetexceptflag
. 我写了一个小测试,发现该feenableexcept
方法有效,而该方法fesetexceptflag
无效。这是两个例子。交换 main 开头的两行注释,得到版本 1 ( fesetexceptflag
) 和版本 2 ( feenableexcept
):
版本 1 输出:
版本 2 输出:
因此,似乎版本 1 在 fenv 中正确设置了异常标志,但未能引发 SIGFPE,而版本 2 未设置异常标志,但确实引发了 SIGFPE。这里发生了什么事?我是否误解了 的文档fesetexceptflag
?我的理解是,它会抓取第一个 arg 中在第二个 arg 中处于活动状态的所有位,并将它们放入 fenv 中(这似乎正在发生)。但是,它似乎无效。另一方面,版本 2 具有 0 掩码 fenv,但成功提高了 SIGFPE。我很困惑。
我在 linux 机器(Red Hat)上使用 gcc 8.2.0,如果有帮助的话。
c++ - 为什么 C++ 中的 fetestexcept 被编译为函数调用而不是内联
我正在评估性能关键/“热”代码中浮点异常的使用(清除和查询)。查看生成的二进制文件,我注意到 GCC 和 Clang 都没有将调用扩展为我期望的内联指令序列。相反,它们似乎生成了对运行时库的调用。这对我的应用程序来说非常昂贵。
考虑以下最小示例:
以及 GCC 产生的输出:https ://godbolt.org/z/jxjzYY
编译器似乎知道他可以将依赖于 CPU 系列的 AVX 指令用于目标(它使用“vmulsd”进行乘法运算)。但是,无论我尝试哪种优化标志,它总是会产生对 glibc 的更昂贵的函数调用,而不是(据我所知)应该执行相应 glibc 函数所做的程序集。
这不是投诉,我可以添加内联程序集。我只是想知道是否可能存在我忽略的细微差异,这可能是 inline-assembly-version 中的错误。
c - feraiseexcept:编译器之间的不同行为以及缺乏实现定义行为的文档
示例代码(t91.c):
调用:
ISO/IEC 9899:2011 (E):
7.6.2.2 fegetexceptflag 函数
feraiseexcept 函数在引发“溢出”或“下溢”浮点异常时是否另外引发“不精确”浮点异常是实现定义的。
但是,gcc的文档和 Microsoft C的文档并没有(或者我找不到)记录feraiseexcept
函数的确切行为。请注意,Clang/LLVM直接通过源代码记录其实现定义的行为。
此外,符合 ISO C 的实施应附有一份文件,该文件定义所有实施定义的和特定于语言环境的特征和所有扩展(ISO/IEC 9899:2011 (E),第 4 节第 8 段)。
问题(终于!):为什么 C 实现不记录所有实现定义的特征/行为?
UPD。是的,GCC 的手册说wrt Library Functions:这些点中的大多数行为都依赖于 C 库的实现,而不是由 GCC 本身定义的。因此,我们必须查看(which is a for )的glibc
实现。feraiseexcept
weak_alias
__feraiseexcept
c - C 标准的 FE_TONEAREST 舍入模式是否保证中间关系舍入为偶数?
我正在编写依赖于 C(特别是 c11)四舍五入到偶数的中途关系的代码。当将带有舍入模式的 rint 用作 FE_TONEAREST 时,我没有在 C 标准中找到说明如何使用 FE_NEAREST 处理关系的保证。ISO C 标准的第 509 页指出
<fenv.h> 中的 fegetround 和 fesetround 函数提供了在由 <fenv.h> 中的舍入方向宏(FE_TONEAREST、FE_UPWARD、FE_DOWNWARD、FE_TOWARDZERO)和值 0、1 表示的 IEC 60559 定向舍入模式中进行选择的工具FLT_ROUNDS 的 、 2 和 3 是 IEC 60559 有向舍入模式。
但是,我在 IEC 60559 标准中找不到任何有关舍入模式的文档。在我的测试机器上,行为是在 FE_TONEAREST 中,关系四舍五入到偶数,我想确保这是由 c11 标准强制执行的,而不是实现定义的。