C++:未改变的浮点值是否有恒定保证?

3
我想知道如果我只是在函数之间传递浮点数值而没有进行进一步的计算,那么这个值是否会改变。我想编写一些使用硬编码值测试此类函数的测试。
例如:
float identity(float f) { return f; }

我能写以下测试吗:

我可以编写以下测试:

TEST() {
    EXPECT(identity(1.8f) == 1.8f);
}

所有副本,没有任何引用。看起来很安全。 - πάντα ῥεῖ
5
是的,除非转换失败,因为将15.8表示为“float”的方式可能与其表示为文字的方式不同,后者是“double”。 - The Paramagnetic Croissant
就像我想的那样,看看那些警告!(http://coliru.stacked-crooked.com/a/259e520a2aac3fa2) - The Paramagnetic Croissant
@ElefEnt 或者,如果你不需要那么多位,可以使用浮点数字面量(15.8f); - The Paramagnetic Croissant
实际上,在使用x87时,除非您传递一些非常特定的标志,否则x+y==identity(x+y)在gcc中可能会返回false。 - Marc Glisse
显示剩余5条评论
3个回答

3

总体而言,C++标准不会做出保证,如果知道这样的保证将导致某些处理器架构的代码不够优化。

旧版x86浮点数处理使用80位寄存器进行计算。仅仅是将一个值从其中一个寄存器移动到64位内存中就会导致舍入发生。


1
如果你 不执行任何损失操作,只是传递浮点数数据,那么可以安全地假定(假设没有干扰或优化错误)这些值将保持不变。只需确保不将浮点值与解释为双精度的文字值进行比较(EXPECT(indentity(1.8f) == 1.8);),或反之亦然。
/paranoid_level on

然而,您应该始终检查目标架构对浮点数的行为,特别是与IEEE 754标准相关的情况:在允许在特定情况下使用IEEE 754异常(例如,在GPU中经常使用的-ftz标志)的系统上,由于结果可能以不同的方式在内部处理,您可能会得到与预期不一致的结果(可能是在组合智能编译器优化时)。一个例子是适用于任何浮点运算的体系结构,其中应用了denormals-are-zero (-daz)策略。


0

这是完全没问题的,值将会保持不变。

正如评论中指出的那样,如果你写成:

TEST() {
    EXPECT(indentity(1.8)  == 1.8f);
    EXPECT(indentity(1.8l) == 1.8f);
}

你可能会遇到问题,因为从int / double进行了隐式转换。 但是,如果你将浮点数与浮点数进行比较,那么完全安全。

参考


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接