4

我知道有些值无法在浮点数中轻松定义,并且只是“近似值”,因此直接“等于”比较经常不起作用。

std::numeric_limits::max 可以准确地存储在浮点数中,并且此代码会按预期运行吗?

float myFloat = std::numeric_limits<float>::max();

//...later...
if(myFloat == std::numeric_limits<float>::max())
{
    //...myFloat hasn't changed...
}
4

3 回答 3

4

对于给定的(非 NaN)float变量,f保证f == f始终为真。由于myFloat设置为某个float值,因此它当然会比较等于相同的值。

您显然正在考虑以下情况:

float f1 = 0.1;
float f2 = 1.0/10;
assert( f1 == f2 );

这可能会失败,但这不会失败:

float f1 = 0.1;
float f2 = 0.1;
assert( f1 == f2 );

尽管存储在变量中的值可能不完全相等,0.1但可能具有不同的值,但您将获得两个变量的相同值,因此它们将比较相等。

无论numeric_limits<float>::max()返回什么值,它都是一个固定值,与自身比较相等。

于 2013-02-25T01:01:49.040 回答
4

是的。

numeric limits是一个类模板,max 是一个静态方法:

  template <class T> class numeric_limits {
  public:
  ...
  static T max() throw(); //constexpr if using C++11
  ...
  };

因此,对于 float 类型,您实际上将使用std::numeric_limits<float>::max()并简单地比较两个相等值的浮点数(只要您在比较之前没有对 myFloat 进行操作)。max() 的值对于您的平台将是一个一致的浮点数,并且将具有与其自身等效的二进制表示。

您将遇到的主要麻烦是尝试使用不同的浮点二进制表示跨平台进行序列化和反序列化。因此,如果您尝试序列化 myFloat 变量并在其他机器上尝试将反序列化值的结果直接与 numeric_limits::max() 进行比较:

if( myFloat == std::numeric_limits<float>::max() )

结果可能不再成立。然后,您需要在二进制表示中对“MAX”的概念进行编码,并以您想要的方式明确解释它。

于 2013-02-25T00:21:51.553 回答
2

对,但是

myFloat += someSmallFloat;

可能不会改变 的值myFloat

如果您想了解更多,有一个关于浮点表示的精彩教程,名为What Every Computer Scientist Should Know About Floating-Point Arithmetic

于 2013-02-24T23:46:54.100 回答