int NA 的内部表示

问题描述 投票:0回答:2

这是关于 R 内部的问题。 R 中如何表示整数 NA 值? 与浮点不同,没有神奇的位序列来表示 NaN。

# Create big array. newer versions of R won't allocate memory to store data
# Instead star/end values are stored internally
a <- 1:1e6 # 

# Change some random value. This will cause and array to be allocated
a[123] <- NA
typeof(a)

此时a仍然是一个整数数组。 a[123]内部如何表示? R 是否使用一些幻数来表示整数为 NA?

我对整数内部表示的主要兴趣与二进制读/写(readBin/writeBin)有关。使用外部源执行二进制 I/O 时如何处理 NA,例如通过套接字?

r
2个回答
7
投票

R用最小整数值来表示NA。在 4 字节系统上,有效整数值通常为 -2,147,483,648 到 2,147,483,647,但在 R

> .Machine$integer.max
[1] 2147483647
> -.Machine$integer.max
[1] -2147483647
> -.Machine$integer.max - 1L
[1] NA
Warning message:
In -.Machine$integer.max - 1L : NAs produced by integer overflow

还有,

> .Internal(inspect(NA_integer_))
@7fe69bbb79c0 13 INTSXP g0c1 [NAM(7)] (len=1, tl=0) -2147483648

0
投票

在内存中,整数的存储方式是:

  • 第一个0L
  • 然后是正整数(升序)
  • 然后
    NA_integer_
  • 然后是负整数(升序)

所以我不会说

NA_integer_
存储为最小整数,即使
.Internal(inspect(NA_integer_))
建议这样做。也许更好的说法是它存储在其他语言通常存储最小整数的地方?

查看下面每个向量的最后 4 个元素。

# first zero
serialize(0L, connection = NULL)
#>  [1] 58 0a 00 00 00 03 00 04 04 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00
#> [26] 00 0d 00 00 00 01 00 00 00 00

# then positive integers (ascending)
serialize(1L, connection = NULL)
#>  [1] 58 0a 00 00 00 03 00 04 04 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00
#> [26] 00 0d 00 00 00 01 00 00 00 01
serialize(.Machine$integer.max, connection = NULL)
#>  [1] 58 0a 00 00 00 03 00 04 04 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00
#> [26] 00 0d 00 00 00 01 7f ff ff ff

# then NA_integer_
serialize(NA_integer_, connection = NULL)
#>  [1] 58 0a 00 00 00 03 00 04 04 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00
#> [26] 00 0d 00 00 00 01 80 00 00 00

# then negative integers (ascending, i.e. descending in absolute value)
serialize(-.Machine$integer.max, connection = NULL)
#>  [1] 58 0a 00 00 00 03 00 04 04 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00
#> [26] 00 0d 00 00 00 01 80 00 00 01
serialize(-1L, connection = NULL)
#>  [1] 58 0a 00 00 00 03 00 04 04 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00
#> [26] 00 0d 00 00 00 01 ff ff ff ff

创建于 2024-10-09,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.