首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果没有实用的STDC FENV_ACCESS,这是否意味着默认的舍入模式?

如果没有实用的STDC FENV_ACCESS,这是否意味着默认的舍入模式?
EN

Stack Overflow用户
提问于 2020-03-17 05:58:45
回答 1查看 194关注 0票数 2

我对C标准的解释有问题,这是取自http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2454.pdf的最新草案。

标准评价

标准定义了pragma STD FENV_ACCESS并声明(7.6.1p2):

代码语言:javascript
运行
复制
The FENV_ACCESS pragma provides a means to inform the implementation when a program might
access the floating-point environment to test floating-point status flags or run under non-default
floating-point control modes.

目前尚不清楚为什么这种必须在非默认浮点控制模式下运行的实用程序。是因为

  • 设置这些非默认模式需要写到控制模式寄存器,或者,即使非默认当前模式已经设置了

,仍然需要使用

在本标准的后面一段中,我们发现:

代码语言:javascript
运行
复制
If part of a program tests floating-point status flags or establishes non-default floating-point
mode settings using any means other than the FENV_ROUND pragmas, but was translated with the
state for the FENV_ACCESS pragma "off", the behavior is undefined.

它看起来像测试当前模式而不改变它不是一种未定义的行为。但同一段中的脚注指出:

代码语言:javascript
运行
复制
In general, if the state of FENV_ACCESS is "off", the translator can assume that the flags are
not tested, and that default modes are in effect, except where specified otherwise by an
FENV_ROUND pragma.

问题

因此,如果没有指定务实FENV_ACCESS,这是否意味着默认舍入模式正在生效?

让我们假设语用FENV_ROUND也不存在,并且编译器假定FENV_ACCESS默认为off,这是向后兼容性所必需的。

示例

请考虑以下源代码:

代码语言:javascript
运行
复制
#include <math.h>
float func_01(float x) {
    return nearbyint(x);
}

函数nearbyint被描述为使用当前舍入模式进行舍入(7.12.9.3)。但是代码没有pragma FENV_ACCESS。这是否意味着可以忽略当前的舍入模式,并且nearbyintroundeven相同?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-17 11:50:13

C稿n2454

我根据目前的C标准(2018年)写了这个答案,但问题是关于即将出台的标准草案。在审查草案时,有重大变化,这一答案不适用。

值得注意的是,n2454草案在7.6.1 2中指出:

…如果程序的一部分测试浮点状态标志或使用FENV_ROUND杂注以外的任何其他方式建立非默认浮点模式设置,但被转换为FENV_ACCESS杂注的状态"off",则该行为是未定义的…。

值得注意的是,在“非默认浮点模式设置”之后出现的C 2018中出现的文本是这样的:

…或在非默认模式设置下运行,…。

C 2018文本意味着,如果用FENV_ACCESS编译的代码设置非默认模式,并设置使用FENV_ACCESS off编译的代码,则行为没有定义,仅仅是因为使用FENV_ACCESS off编译的代码在非默认模式下运行。草案文本不包含此内容,这似乎意味着调用方可以更改使用FENV_ACCESS off编译的模式和调用代码,并且应该定义行为。这意味着用FENV_ACCESS off编译的代码必须准备好以任何浮点模式运行.

草案中的同一段也载有这一新案文:

(当执行从以FENV_ACCESS "off“转换为用FENV_ACCESS转换为"on”的部分时,浮点状态标志的状态未指定,浮点控制模式有其默认设置)。

考虑一下,当例程A和FENV_ACCESS调用例程B时,FENV_ACCESS关闭时会发生什么。当B返回时,控制从程序的访问部分传递到程序的访问部分。上面的句子说浮点控制模式随后处于其默认设置中。换句话说,从访问关闭例程返回必须将浮点模式更改为默认模式。这听起来很奇怪。因此,我不准备更新这一答复,以便很好地涵盖草案。

C 2018的答复

目前还不清楚为什么在非默认的浮点控制模式下运行这种实用程序是必要的.

这是因为它可能(取决于C实现),编译器生成的代码必须是不同的,如果浮点操作不知道处于默认模式。例如,当编译FENV_ACCESS设置为off的代码时,编译器可以将对sin的调用编译为对假定默认舍入的快速版本的调用。但是,如果FENV_ACCESS设置为on,它将将调用编译到一个较慢的版本,该版本测试舍入模式,并使用正弦函数的相应实现。

因为必须生成的代码对于onoff版本是不同的,所以编译器必须知道FENV_ACCESSon还是off

所以如果没有指定FENV_ACCESS,是否意味着默认的舍入模式生效了?

不是的。如果不存在FENV_ACCESS实用程序,则编译器处于默认状态,可以是onoff,这是实现定义的。

如果默认值是off,并且没有实用程序,那么,是的,默认的舍入模式应该是有效的,这意味着,如果您正确地设计了程序,那么使用无FENV_ACCESS杂注编译的任何代码都不会在非默认舍入模式下执行。这要由程序设计人员来确保。

函数nearbyint被描述为使用当前舍入模式进行舍入(7.12.9.3)。但是代码没有pragma FENV_ACCESS。这是否意味着可以忽略当前的舍入模式,并且nearbyintroundeven相同?

如果将FENV_ACCESS设置为off的代码(默认情况下或显式)调用nearbyint,则编译器可以假定默认舍入模式有效,并且可以调用本身采用默认舍入模式的快速nearbyint版本。

请注意,圆周至最近的关系-甚至是压倒默认舍入模式,但这不是指定的C标准,除非附件F是有效的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60716929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档