Scheme 中的科学记数法
Scientific notation in Scheme
我正在做SICP的练习。
在 Ex1.22 中,我有一个关于 Scheme 中科学记数法性能的问题。
这个练习是找出大于指定值的指定数量的素数。
; code to check whether a number is prime
(define (smallest-divisor n)
(find-divisor n 2))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else (find-divisor n (1+ test-divisor)))))
(define (divides? a b)
(= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
; code to find prime numbers
; (search-for-primes 10 3) means find 3 prime numbers larger than 10
; the prime numbers and the time taken will be printed
(define (search-for-primes start count)
(define (iter n c)
(cond ((= c 0) (newline) (display "Done"))
(else (iter (+ n 2) (- c (timed-prime-test n))))))
(iter (if (even? start) (1+ start) start)
count))
(define (timed-prime-test n)
(newline)
(display n)
(start-prime-test n (runtime)))
(define (start-prime-test n start-time)
(cond ((prime? n)
(report-prime (- (runtime) start-time))
1)
(else 0)))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
我的问题是以下两个调用的性能差异:
1 ]=> (search-for-primes 1000000000000 3)
1000000000039 *** 2.319999999999993
1000000000061 *** 2.3799999999999955
1000000000063 *** 2.3599999999999994
1 ]=> (search-for-primes 1e12 3)
1000000000039. *** 4.990000000000009
1000000000061. *** 4.960000000000008
1000000000063. *** 4.959999999999994
显然,科学记数法需要更多时间。为什么会这样?
我的代码是 运行 在最新版本的 MIT-Scheme 上:
MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Copyright (C) 2018 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Image saved on Wednesday October 31, 2018 at 7:14:37 PM
Release 10.1.2 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/i386 4.118
虽然文字 1000000000000
在 Scheme 中被读作一个精确的整数,但 1e12
不被理解为精确的并且将成为一个浮点数。要对精确数字使用科学计数法,您应该使用 #e
前缀或使用 inexact->exact
:
(eqv? 1000000000000 1e12) ; ==> #f (not the same value)
(eqv? 1000000000000 #e1e12) ; ==> #t (the same value)
(eqv? 1000000000000 (inexact->exact 1e12)) ; ==> #t (the same value)
另外,当数字不是整数时,它变成有理数:
#e0.5 ; ==> 1/2
为了完整起见,您也可以反其道而行之。例如。 #i1000000000000
等价于 1e12
等价于 (exact->inexact 1000000000000)
.
限制
在 R6RS 之前,不需要有一个完整的数字塔。该报告甚至提到仅包含浮点数的 Scheme 可能会有用。对于 R5RS 和更早版本,您应该查阅实施文档以查看它是否支持完整的数字塔。 MIT Scheme 在他们的文档中声明他们实现了完整的数字塔。
我正在做SICP的练习。
在 Ex1.22 中,我有一个关于 Scheme 中科学记数法性能的问题。
这个练习是找出大于指定值的指定数量的素数。
; code to check whether a number is prime
(define (smallest-divisor n)
(find-divisor n 2))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else (find-divisor n (1+ test-divisor)))))
(define (divides? a b)
(= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
; code to find prime numbers
; (search-for-primes 10 3) means find 3 prime numbers larger than 10
; the prime numbers and the time taken will be printed
(define (search-for-primes start count)
(define (iter n c)
(cond ((= c 0) (newline) (display "Done"))
(else (iter (+ n 2) (- c (timed-prime-test n))))))
(iter (if (even? start) (1+ start) start)
count))
(define (timed-prime-test n)
(newline)
(display n)
(start-prime-test n (runtime)))
(define (start-prime-test n start-time)
(cond ((prime? n)
(report-prime (- (runtime) start-time))
1)
(else 0)))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
我的问题是以下两个调用的性能差异:
1 ]=> (search-for-primes 1000000000000 3)
1000000000039 *** 2.319999999999993
1000000000061 *** 2.3799999999999955
1000000000063 *** 2.3599999999999994
1 ]=> (search-for-primes 1e12 3)
1000000000039. *** 4.990000000000009
1000000000061. *** 4.960000000000008
1000000000063. *** 4.959999999999994
显然,科学记数法需要更多时间。为什么会这样?
我的代码是 运行 在最新版本的 MIT-Scheme 上:
MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Copyright (C) 2018 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Image saved on Wednesday October 31, 2018 at 7:14:37 PM
Release 10.1.2 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/i386 4.118
虽然文字 1000000000000
在 Scheme 中被读作一个精确的整数,但 1e12
不被理解为精确的并且将成为一个浮点数。要对精确数字使用科学计数法,您应该使用 #e
前缀或使用 inexact->exact
:
(eqv? 1000000000000 1e12) ; ==> #f (not the same value)
(eqv? 1000000000000 #e1e12) ; ==> #t (the same value)
(eqv? 1000000000000 (inexact->exact 1e12)) ; ==> #t (the same value)
另外,当数字不是整数时,它变成有理数:
#e0.5 ; ==> 1/2
为了完整起见,您也可以反其道而行之。例如。 #i1000000000000
等价于 1e12
等价于 (exact->inexact 1000000000000)
.
限制
在 R6RS 之前,不需要有一个完整的数字塔。该报告甚至提到仅包含浮点数的 Scheme 可能会有用。对于 R5RS 和更早版本,您应该查阅实施文档以查看它是否支持完整的数字塔。 MIT Scheme 在他们的文档中声明他们实现了完整的数字塔。