NA_REAL和NAN的区别 [英] Difference between NA_real_ and NaN

查看:18
本文介绍了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 formatmultiple 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屋!

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