首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检查一个数字是否为Clojure中的Fibonacci数?

如何检查一个数字是否为Clojure中的Fibonacci数?
EN

Stack Overflow用户
提问于 2014-12-14 09:00:55
回答 1查看 159关注 0票数 1

输入:一个正整数。

输出:基于测试的真/假。

以下是我的尝试:

代码语言:javascript
复制
(defn is-a-fib? [x]
  "Check whether x is a fibonacci number.
   Algorithm: test whether 5x^2+4 or 5x^2-4 is a perfect square."
  (let [a (+' (*' (Math/pow x 2) 5) 4)                      ; 5x^2+4
        b (-' (*' (Math/pow x 2) 5) 4)                      ; 5x^2-4
        sqrt-a (Math/sqrt a)
        sqrt-b (Math/sqrt b)]
    (or (== (*' sqrt-a sqrt-a)
            (*' (Math/floor sqrt-a) (Math/floor sqrt-a)))  ; Test whether n is a perfect square
        (== (*' sqrt-b sqrt-b)
            (*' (Math/floor sqrt-b) (Math/floor sqrt-b))))))

问题是:这段代码不适用于大量的代码。我认为它可能会导致堆栈溢出。有更好的办法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-14 14:26:41

Math/powMath/sqrtMath/floor操作在精度范围有限的double上工作,对它们的操作将有舍入错误。

如果你从这个角度来看,事情可能会因为四舍五入而脱轨,但是当你用完精度(15到17小数位数)时,它们真的会出错。

第一个n_th Fibonnacci (该算法为后续整数提供假正数)是与_n = 74相关联的16位整数。

代码语言:javascript
复制
(is-a-fib? 1304969544928657)
=> true
(is-a-fib? 1304969544928658)
=> true

编辑:添加避免double的任意精度解决方案:

主要的困难在于缺乏整数平方根算法。

这个Java实现可以被翻译成Clojure:

代码语言:javascript
复制
(defn integer-sqrt [n]
  (let [n (biginteger n)]
    (loop [a BigInteger/ONE
           b (-> n (.shiftRight 5) (.add (biginteger 8)))]
      (if (>= (.compareTo b a) 0)
        (let [mid (-> a (.add b) (.shiftRight 1))]
          (if (pos? (-> mid (.multiply mid) (.compareTo n)))
            (recur a (.subtract mid BigInteger/ONE))
            (recur (.add mid BigInteger/ONE) b)))
        (dec a)))))

在此之后,您可以定义任意精度的完美平方测试:

代码语言:javascript
复制
(defn perfect-square? [n]
  (let [x (integer-sqrt n)]
    (= (*' x x) n)))

并更新您的实现以使用它:

代码语言:javascript
复制
(defn is-a-fib? [x]
  "Check whether x is a fibonacci number.
   Algorithm: test whether 5x^2+4 or 5x^2-4 is a perfect square."
  (let [a (+' (*' (*' x x) 5) 4)                            ; 5x^2+4
        b (-' (*' (*' x x) 5) 4)]                           ; 5x^2-4
    (or (perfect-square? a)
        (perfect-square? b))))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27467800

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档