使用NaN检查变量是否已分配是一种好习惯吗? [英] Is it good practice to use NaN to check if a variable is assigned or not ?

查看:69
本文介绍了使用NaN检查变量是否已分配是一种好习惯吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我不能使用BOOST,C ++ 11或C ++ 14等功能,比如std :: experimental :: optional)



使用它是不错的做法NaN检查是否分配了双变量? (如果变量值在语义上存在与否)



我正在读取/解析包含double值的XML文件;其中一些值并不总是使用,并且在XML文件中将为空。

将值写回XML文件时,如果我的程序没有分配值,我不想回写值。





< node attribute =/> 




我的代码中的
我有类似的东西(伪代码)



 void ReadAttribute(string attributeName,double& value)
{
string tmp;
ReadXLMAttribute(attributeName,tmp);
if(tmp.empty)
value = std :: numeric_limits< double> :: quiet_NaN();
else
value = ConvertStringToDouble(tmp);

}

void WriteAttribute(string attributeName,double value)
{
string tmp;
if(value! - NaN)
{
tmp = ConvertDoubleToString(value)
}
else
{
tmp =;
}
WriteXMLAttribute(attributeName,tmp);

}

double attribute = std :: numeric_limits< double> :: quiet_NaN();

ReadAttribute(attribute,attribute);

WriteAttribute(属性,属性);





这有意义吗?



谢谢。



Max。

解决方案

它会工作,但我不会这样做。

首先,你知道, NaN 可能是实际的结果表达,因此你给它更多的意义。另一点是你可能最终(如果你在使用前忘了检查它)用这样的NaN值执行一些计算。

使用 struct 或者 class 带有布尔 isValid llooks就像浪费资源一样,在我看来,它是一种更清洁,更轻松的方法(对于实例你可以在表达式中使用它之前自动进行有效性检查。


我确信这种做法已经足够好了,但是你应该在初始化时总是分配NaN。



更准确地说,你应该使用非数字来表达不是数字的概念,无论它是什么。 C Pallini是对的:它可能是算术运算的结果。但是有些情况下你真的可以使用NaN初始化值。这取决于你做了什么。



一个很好的例子:你有一系列的价值观;然后数据采集用值填充它。某些测量可能会失败,然后您以某种方式呈现数据。如何初始化这些值?如果默认初始化它们,则默认值为0.0。但测量结果也可以给你0.0,那么它与未初始化的值(例如,测量失败)有何不同?所以,NaN肯定更好。 (更准确地说,使用0.0的默认初始化是不可接受的。)



您还应该记住NaN是非常合法的,因为标准的IEEE 754:http://en.wikipedia.org/wiki/IEEE_floating_point [ ^ ]。



-SA

有意义取决于您的应用程序需要实现的目标:



- 内部操作是否需要从值中识别未分配的值处理结果?



- 你需要区分未分配,无限,下溢,零或NaN值吗?您是否还需要在输出中正确表示这些状态? (参见 http://www.cplusplus.com/reference/cmath/fpclassify/ [ ^ ]了解更多信息)



- 内部流程甚至可以处理未分配的数字还是总是需要有效值?如果是这样,未指定的数字是否有合理的默认值?



- 如果没有改变,是否需要重现与读取完全相同的输出?



- 是否存在任何范围限制,您可以利用这些限制来定义代表某些状态的幻数,例如未分配?



最常见的解决方案是为每个指示其当前状态的值维护一个单独的标志。优点是您可以定义任意数量的状态并将其用于任何特定类型,而不受任何限制。缺点是对内存,处理和代码的附加要求。



第二种选择是(ab)使用变量的任何其他可能状态一个指标。缺点是无法辨别该状态的变量是否只是未分配或通过处理达到该值。



第三种选择是定义一个特定的法线表示未分配状态的值:如果可以确保该值不在该类型的任何变量的正常有效值范围内,这显然只能起作用。因此,在大多数情况下,这并不实用。将浮点值与给定常量完全比较也有点棘手。


(I cannot use BOOST, C++11 or C++14 features like std::experimental::optional)

Is it good practice to use NaN to check if a double variable is assigned or not ? (if a variable value is semantically there or not)

I'm reading/parsing a XML file that contain double values; some of those values are not always used and will be "empty" in the XML file.
When writing back the value to the XML file, I don't want to write back a value if it was not assigned by my program.


<node attribute=""/> 



in my code I have something like (pseudo code)

void ReadAttribute( string attributeName, double& value )
{
  string tmp;
  ReadXLMAttribute( attributeName, tmp );
  if ( tmp.empty )
    value = std::numeric_limits<double>::quiet_NaN();
  else
    value = ConvertStringToDouble( tmp );

}

void WriteAttribute ( string attributeName, double value )
{
  string tmp;
  if ( value !- NaN )
  { 
     tmp = ConvertDoubleToString( value )
  } 
  else
  { 
     tmp = "";
  }
  WriteXMLAttribute( attributeName, tmp );

}

double attribute = std::numeric_limits<double>::quiet_NaN();

ReadAttribute ("attribute", attribute );

WriteAttribute("attribute", attribute );



Does that make sense ?

Thanks.

Max.

解决方案

It would work but I wouldn't do that.
First of all, you know, NaN could be the result of an actual expression, hence you are giving it more meanings. Another point is you could end up (if you forgot to check it before use) performing some computation with such NaN values.
While using a struct or class with a boolean isValid llooks like wasting resources, it is, in my opinion a cleaner and painless approach (for instance you could automate validity check before use it in expressions).


I am sure this practice is good enough, but then you should always assign NaN at the moment of initialization.

More exactly, you should use Not a Number to conduct the idea of not a number, whatever it is. C Pallini is right: it can be a result of arithmetic operation. But there are cases when you really can initialize the value with NaN. It depends on what you do.

One good example: you have an array of values; and then data acquisition fills it with values. Some measurement may fail, and then you present the data somehow. How the values should be initialized? If you initialize them by default, the default is 0.0. But the measurements can give you 0.0, too, so how it could be different from not initialized value (say, failed measurement)? So, NaN is certainly better. (More exactly, default initialization with 0.0 is simply unacceptable.)

You should also remember that NaN is quite legitimate, because of the standard IEEE 754: http://en.wikipedia.org/wiki/IEEE_floating_point[^].

—SA


What makes sense depends on what your application needs to achieve:

- do the internal operations need to discern unassigned values from values that are the result of processing?

- do you need to distinguish unassigned, infinite, underflow, zero, or NaN values? Do you need to properly represent these states in output too? (see http://www.cplusplus.com/reference/cmath/fpclassify/[^] for more info)

- can the internal processes even deal with unassigned numbers or do they always need a valid value? If so, is there a reasonable default value for unassigned numbers?

- Is there a need to reproduce exactly the same output as you are reading if nothing is changed?

- are there any range limitations that you can take advantage of for the purpose of defining magic numbers that represent certain states such as being unassigned?

The most general solution would be to maintain a separate flag for each value that indicates its current state. The advantage is that you can define an arbitrary number of states and use it for any specific type, without restrictions. The disadvantages are the added requirements for memory, processing, and code.

A second option would be to (ab)use any of the other possible states of a variable as an indicator. The disadvantage is the inability to discern whether a variable in that state was simply unassigned or arrived at that value through processing.

A third option would be to define a specific normal value that represents the unassigned state: this obviously only works, if you can make sure that value is not within the normal valid range of values for any variable of that type. It is therefore not that practical, in most cases. It is also somewhat tricky to exactly compare a floating point value to a given constant.


这篇关于使用NaN检查变量是否已分配是一种好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆