为了避免在库代码中引发“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?