NA_REAL和NAN的区别 [英] Difference between NA_real_ and NaN
本文介绍了NA_REAL和NAN的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
当我使用.Internal(inspect())
toNA_real_
和NaN
时,它返回
> .Internal(inspect(NA_real_))
@0x000001e79724d0e0 14 REALSXP g0c1 [REF(2)] (len=1, tl=0) nan
> .Internal(inspect(NaN))
@0x000001e797264a88 14 REALSXP g0c1 [REF(2)] (len=1, tl=0) nan
它们唯一的区别似乎是内存地址。
但是,当我将NA_real_
和NaN
强制转换为字符时,它返回
> as.character(c(NaN, NA_real_))
[1] "NaN" NA
我理解它应该返回上面的结果,因为NaN
不能是字符,它将被强制为"NaN"
,但NA_real
将被强制为NA_character_
。但考虑到他们的直觉是一样的,R怎么能为他们返回不同的结果呢?
提前感谢您的建议!
推荐答案
Well。首先,记住NA
是一个在C中没有等价的R概念,因此,必然需要在C中以不同的方式表示NA
。.Internal(inspect())
没有进行这种区分的事实并不意味着它不是在其他地方进行的。事实上,碰巧.Internal(inspect())
使用Rprintf
打印值的内部双浮点表示形式。实际上,R NA被编码为C浮点类型中的NaN值。
其次,您观察到"它们唯一的区别是内存地址。"-那又如何?至少在概念上,不同的内存地址完全足以区分NA和NAN,不需要更多内容。
但事实上,R通过不同的途径区分这些值。这是可能的,因为IEEE 754 double precision floating point format有multiple different representations of NaN,并且R为Nas:保留了一个特定的static double R_ValueOfNA(void)
{
/* The gcc shipping with Fedora 9 gets this wrong without
* the volatile declaration. Thanks to Marc Schwartz. */
volatile ieee_double x;
x.word[hw] = 0x7ff00000;
x.word[lw] = 1954;
return x.value;
}
和:
/* is a value known to be a NaN also an R NA? */
int attribute_hidden R_NaN_is_R_NA(double x)
{
ieee_double y;
y.value = x;
return (y.word[lw] == 1954);
}
int R_IsNA(double x)
{
return isnan(x) && R_NaN_is_R_NA(x);
}
int R_IsNaN(double x)
{
return isnan(x) && ! R_NaN_is_R_NA(x);
}
(src/main/arithmetic.c
)
这篇关于NA_REAL和NAN的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文