检查一个数字是整数还是非整数有理数
Check if a number is an integer or non-integer rational
我如何测试一个数字,看看它是否是整数而不是非整数有理数?
剧透警告取自4clojure.com问题。
上下文
考虑这个函数:
(defn qux [n i]
(reduce + (range 1 (/ n i))))
区间的最后一个元素是小于n
且能被i整除的正整数个数
user> (qux 10 3) ; 3, 6, & 9 are divisible by 3, sum(1, 2, 3) = 6
6
user> (qux 10 5) ; 5 is divisible by 5, sum(1) = 1
1
我想生成总和,而不生成范围。 sum(1..N) = N(N + 1)/2
救援。
问题在于 N
是严格小于 n / i
的最大整数。我的错误尝试是:
(defn how-many [n i]
(int (/ n i)))
(defn sum-1-to-N [n]
(/ (* n (+ n 1)) 2))
(defn qux-prime [n i]
(sum-1-to-N (how-many n i)))
user> (qux-prime 10 5)
3
所以我想测试(/ n i)
的结果,如果是整数则减一,否则使用int
截断。 (不使用 floor
因为我不想导入整个数字塔,因为不确定如何在 4clojure 上做到这一点。)
您可以使用 built-in integer?
function:
=> (integer? (/ 10 5)) ; true
这是一个完整的例子:
(defn qux-prime [n i]
(let [r (/ n i)
n (if (integer? r) (dec r) (int r))]
(/ (* n (+ n 1)) 2)))
我在另一个上下文中遇到了这种情况,发现
(if (== (int n) n) ; test to see if n is an integer - done this way (instead
(do-if-true) ; of integer?) so that float integers will be detected
(do-if-false)) ; correctly
效果很好。
分享和享受。
有几个直接处理整数的核心函数,由于您的问题涉及这些,因此它可能比依赖 int
函数强制转换要好一点:
给出 qux
:
(defn qux2 [n i]
(let [p (quot n i)
q (if (zero? (rem n i)) (dec p) p)]
(quot (* q (inc q)) 2)))
我用 criterium 代替它:
(require '[criterium.core :as c])
(let [p (rand-int 1000000)
q (rand-int 10000)
N 1000]
(println "=========" p q)
(c/quick-bench (dotimes [_ N] (qux p q)))
(c/quick-bench (dotimes [_ N] (qux2 p q)))
(c/quick-bench (dotimes [_ N] (qux-prime p q))))
在我的 mbp 上:
========= 364347 9361
...
Execution time mean : 6.111392 ms [=> with reduce]
...
Execution time mean : 69.042004 µs [=> with quot, rem]
...
Execution time mean : 294.989561 µs [=> with int, integer?]
...
看起来在处理特定于整数的函数时,您有显着的性能提升。
我如何测试一个数字,看看它是否是整数而不是非整数有理数?
剧透警告取自4clojure.com问题。
上下文
考虑这个函数:
(defn qux [n i]
(reduce + (range 1 (/ n i))))
区间的最后一个元素是小于n
且能被i整除的正整数个数
user> (qux 10 3) ; 3, 6, & 9 are divisible by 3, sum(1, 2, 3) = 6
6
user> (qux 10 5) ; 5 is divisible by 5, sum(1) = 1
1
我想生成总和,而不生成范围。 sum(1..N) = N(N + 1)/2
救援。
问题在于 N
是严格小于 n / i
的最大整数。我的错误尝试是:
(defn how-many [n i]
(int (/ n i)))
(defn sum-1-to-N [n]
(/ (* n (+ n 1)) 2))
(defn qux-prime [n i]
(sum-1-to-N (how-many n i)))
user> (qux-prime 10 5)
3
所以我想测试(/ n i)
的结果,如果是整数则减一,否则使用int
截断。 (不使用 floor
因为我不想导入整个数字塔,因为不确定如何在 4clojure 上做到这一点。)
您可以使用 built-in integer?
function:
=> (integer? (/ 10 5)) ; true
这是一个完整的例子:
(defn qux-prime [n i]
(let [r (/ n i)
n (if (integer? r) (dec r) (int r))]
(/ (* n (+ n 1)) 2)))
我在另一个上下文中遇到了这种情况,发现
(if (== (int n) n) ; test to see if n is an integer - done this way (instead
(do-if-true) ; of integer?) so that float integers will be detected
(do-if-false)) ; correctly
效果很好。
分享和享受。
有几个直接处理整数的核心函数,由于您的问题涉及这些,因此它可能比依赖 int
函数强制转换要好一点:
给出 qux
:
(defn qux2 [n i]
(let [p (quot n i)
q (if (zero? (rem n i)) (dec p) p)]
(quot (* q (inc q)) 2)))
我用 criterium 代替它:
(require '[criterium.core :as c])
(let [p (rand-int 1000000)
q (rand-int 10000)
N 1000]
(println "=========" p q)
(c/quick-bench (dotimes [_ N] (qux p q)))
(c/quick-bench (dotimes [_ N] (qux2 p q)))
(c/quick-bench (dotimes [_ N] (qux-prime p q))))
在我的 mbp 上:
========= 364347 9361
...
Execution time mean : 6.111392 ms [=> with reduce]
...
Execution time mean : 69.042004 µs [=> with quot, rem]
...
Execution time mean : 294.989561 µs [=> with int, integer?]
...
看起来在处理特定于整数的函数时,您有显着的性能提升。