【问题标题】:Negative Fibonacci term F(50) with R package "Rcpp"带有 R 包“Rcpp”的负斐波那契项 F(50)
【发布时间】:2017-05-02 18:58:35
【问题描述】:

我使用了 R 包“Rcpp”提供的示例,并获得了负的 50-th Fibonacci 项:

fib <- Rcpp::cppFunction(
  'int fibonacci(const int x) {
      if (x == 0) return(0); 
      if (x == 1) return(1);
      return (fibonacci(x - 1)) + fibonacci(x - 2);
  }')

fib(50)
# [1] -298632863

这让我好奇地检查了直到 F(50) 的整个序列:

sapply(seq(50), fib)

事实证明,否定项以 F(47) 开头:

[1]   1  1  2  3  5  8  13  21  34
.
.
[10]  55  89 144 . . .
.
.
[46]  1836311903 -1323752223   512559680  -811192543  -298632863

欢迎任何见解!

sessionInfo()
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 14393)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] compiler_3.4.0 tools_3.4.0    inline_0.3.14  Rcpp_0.12.10  

【问题讨论】:

  • 看起来您正在返回int。您可能想检查有符号整数值可以采用的值范围。
  • 我改为“long”,结果相似:-298632863
  • 你能换成long long吗?见here
  • 尝试“long long”以错误告终。我改为“float”,结果是 F(50) = 12586267648,没有其他项到 F(50) 是负数
  • @DragosBandur 那时你已经失去了精确度。第 50 个数字是序列实际上是 12,586,269,025。 R 本身不支持无符号 4 字节整数。 .Machine$integer.max 已经够高了

标签: c++ r


【解决方案1】:

就像 MrFlick 评论的那样,这可能与 int 的范围有关。

如果我们假设这是一个 32 位整数,则该整数的最大值为 2^31 - 1,即 2,147,483,647,最小值为 -2^31,第 32 位为符号 (正或负)。

对于斐波那契数列,第一个大于 32 位整数可以处理的数字是第 47 项,应该是 2,971,215,073,超过最大值 2,147,483,647。

在十六进制中,第 47 项将是 0xB11924E1,它被解释为设置了符号位的整数,因此被解释为负数,-1323752223。

查看此图示的一种简单方法是在程序员模式下使用 Windows 计算器,它可以显示为哪个数字设置了哪些位,并且您可以在 Qword(64 位)和 Dword(32 位)之间切换以查看32 位的限制。

See this link for expected Fibonacci values

【讨论】:

  • 查看我上面的最后一条评论
【解决方案2】:

您似乎超出了 C++ 整数的最大值 2147483647。这是一个用 R 本身编写的更有效的实现,它使用循环而不是递归结构。这也避免了增长向量。

fibo <- function(x) {

    if (x == 0) {
        return(0)
    } else if (x %in% 1:2) {
        return(1)
    }

    the.seq <- rep(NA, x)
    the.seq[1:2] <- 1
    for (i in 3:x) {
        the.seq[i] <- the.seq[i - 1] + the.seq[i - 2]
    }

    return(the.seq[x])
}

【讨论】:

  • 我试图避免迭代。我在尝试使用 R、R+Rcpp 和编译的 R 递归(使用 compf())对三个递归进行基准测试时发现了这一点。似乎使用“浮动”有所帮助。
猜你喜欢
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
  • 2018-07-11
  • 2015-10-19
  • 2011-02-20
相关资源
最近更新 更多