为了避免在库代码中引发“FE_INEXACT”,我应该采取啥措施?

Posted

技术标签:

【中文标题】为了避免在库代码中引发“FE_INEXACT”,我应该采取啥措施?【英文标题】:To what lengths should I go in order to avoid raising `FE_INEXACT` in library code?为了避免在库代码中引发“FE_INEXACT”,我应该采取什么措施? 【发布时间】:2020-08-03 01:57:12 【问题描述】:

我正在用 C 语言创建一个库,其中包含用于一般用途的通用数据结构、便利函数等。在其中,我实现了一个动态数组,并且出于here 解释的原因,我选择了黄金比例作为增长因素。但是,这必然涉及浮点数的乘法,如果它们具有较大的有效位,这可能会导致 FE_INEXACT 被提升。

当我实现它时,我的印象是,由于该库是通用的,因此必须尽可能避免浮点异常。我首先尝试了类似

fenv_t fenv;
feholdexcept(&fenv);
// expand dynamic array
feclearexcept(FE_INEXACT);
feupdateenv(&fenv);

,但是这样做的时间成本太高了,不值得。

最终,我想出了一个时间成本可以忽略不计的解决方案。虽然没有完全避免FE_INEXACT,但它非常不可能。即,

size_t newCapacity = nearbyint((double)(float)PHI * capacity);

这只会在当前容量非常大的情况下引发FE_INEXACT,至少对于符合 IEEE 754 标准的编译器而言。

我开始怀疑我的努力是否已经解决了一个相对无关的问题。对于库代码,期望用户在必要时处理FE_INEXACT 的提升是否合理,还是应该在库内避免?在后一种情况下,与效率等其他因素相比,这个问题有多重要?

【问题讨论】:

【参考方案1】:

我应该走多远...

根本没有。几乎没有人使用fenv.h,编译器甚至不完全支持它(他们进行错误地忽略或改变浮点环境的转换),如果有人调用你的代码正在使用它,要求他们保存/恢复异常是完全合理的说明对您的图书馆的调用。此外,大多数情况下,如果您正在执行引发 FE_INEXACT 的操作,正是因为您将返回的结果不准确,因此在语义上引发它是合适的.

【讨论】:

以上是关于为了避免在库代码中引发“FE_INEXACT”,我应该采取啥措施?的主要内容,如果未能解决你的问题,请参考以下文章

如何重构我的代码以避免从类外部引发事件?

如何在库模块的代码中获取主要的 applicationId?

cocoapods 安装代码在库上崩溃后

Android Studio 的调试器不会在库模块中的断点处停止

如何在库项目中引用资产

在库的情况下对函数的未定义引用