c++ - 是否保证浮点变量的副本将按位等同于原始变量?
问题描述
我正在研究浮点确定性,并且已经研究了许多令人惊讶的不确定性的潜在原因,我开始对复制浮点数感到偏执:
C++ 标准中的任何内容或一般情况下是否向我保证浮点左值在被复制到另一个浮点变量或用作 const-ref 或按值参数时,将始终按位等效于原始值?
任何事情都会导致复制的浮点数按位与原始值等效,例如更改浮点环境或将其传递到不同的线程?
这是一些基于我用来检查测试用例中浮点值等价性的示例代码,这个会失败,因为它需要 FE_TONEAREST:
#include <cfenv>
#include <cstdint>
// MSVC-specific pragmas for floating point control
#pragma float_control(precise, on)
#pragma float_control(except, on)
#pragma fenv_access(on)
#pragma fp_contract(off)
// May make a copy of the floats
bool compareFloats(float resultValue, float comparisonValue)
{
// I was originally doing a bit-wise comparison here but I was made
// aware in the comments that this might not actually be what I want
// so I only check against the equality of the values here now
// (NaN values etc. have to be handled extra)
bool areEqual = (resultValue == comparisonValue);
// Additional outputs if not equal
// ...
return areEqual;
}
int main()
{
std::fesetround(FE_TOWARDZERO)
float value = 1.f / 10;
float expectedResult = 0x1.99999ap-4;
compareFloats(value, expectedResult);
}
我是否必须担心,如果我将浮点值传递给比较函数,即使它是左值,它在另一边的结果可能会有所不同?
解决方案
不,没有这样的保证。
次规范、非规范化浮点和 NaN 都是位模式可能不同的情况。
我相信带符号的负零可以在分配时变成带符号的正零,尽管 IEEE754 不允许这样做。
推荐阅读
- c - 我可以在不手动复制整个矩阵的情况下更改指针的地址吗?
- openrefine - 如何在 OpenRefine ReST-API 的“创建项目”Post Rquest 中传递选项 JSON?
- angular7 - Angular 7 - 多个插座:错误:无法激活已激活的插座
- python - Django Rest Framework APIView 中的分页控件
- r - 统计某个数字的发生次数,将结果添加到新列
- sql - SQL 事务数据:根据购物篮行级别数据,确定产品作为购物篮中唯一产品出现的购物篮数量
- excel - 连续工作表切换循环
- angular - 添加 Firestore 文档作为文档更新的一部分
- python - DRF 如果用户没有投票,则返回 201,如果已投票,则返回 400
- lighthouse - 谷歌灯塔速度指数 100% 视觉完成的帧定义