可以将C ++ std :: numeric_limits <float> :: max()准确地存储在float中并稍后进行比较吗?</float>

时间:2013-02-24 23:43:36

标签: c++ floating-accuracy

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

std :: numeric_limits :: max可以准确地存储在一个浮点数中吗,这段代码会按预期运行吗?

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

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

3 个答案:

答案 0 :(得分: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”的概念进行编码,并明确地将其解释为您想要的。

答案 1 :(得分:3)

对于给定的(非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(),它都是一个固定值,将与自身进行比较。

答案 2 :(得分:2)

是的,但是

myFloat += someSmallFloat;

可能不会更改myFloat的值。

如果您想了解更多信息,可以使用名为What Every Computer Scientist Should Know About Floating-Point Arithmetic的浮点表示方法。