forked from larcenists/larceny
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Faster bitwise operations on bignums (ticket larcenists#798)
- Loading branch information
Showing
3 changed files
with
60 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
10 | ||
200 | ||
(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 | ||
83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 | ||
167 173 179 181 191 193 197 199) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
;;; Implementation of the Sieve of Eratosthenes, using a bitset. | ||
;;; The bitset is immutable and thus copied on each modification, | ||
;;; which ruins the efficiency of the algorithm but makes it a | ||
;;; good benchmark for bitwise operations. | ||
|
||
(import (rnrs base) | ||
(rnrs arithmetic bitwise) | ||
(rnrs io simple)) | ||
|
||
;;; A bitset is a non-negative exact integer. | ||
|
||
;; Returns a list of the indexes at which the bitset has a one. | ||
(define (bitset->list bs) | ||
(define (loop bs l) | ||
(if (zero? bs) | ||
l | ||
(let ((k (bitwise-first-bit-set bs))) | ||
(loop (bitwise-copy-bit bs k 0) | ||
(cons k l))))) | ||
(reverse (loop bs '()))) | ||
|
||
;; Returns a list of the prime numbers within the given bound. | ||
(define (primes<= n) | ||
(define (filter-loop k m comps) | ||
(if (> m n) | ||
comps | ||
(filter-loop k (+ k m) (bitwise-copy-bit comps m 1)))) | ||
(define (base-loop i comps) | ||
(cond ((> i n) | ||
comps) | ||
((bitwise-bit-set? comps i) | ||
(base-loop (+ i 1) comps)) | ||
(else | ||
(base-loop (+ i 1) (filter-loop i (+ i i) comps))))) | ||
(bitset->list | ||
(bitwise-not | ||
(bitwise-ior (base-loop 2 3) | ||
(bitwise-arithmetic-shift-left -1 (+ n 1)))))) | ||
|
||
(define (main) | ||
(let* ((count (read)) | ||
(input1 (read)) | ||
(output (read)) | ||
(s2 (number->string count)) | ||
(s1 (number->string input1)) | ||
(name "primes")) | ||
(run-r6rs-benchmark | ||
(string-append name ":" s1 ":" s2) | ||
count | ||
(lambda () (primes<= (hide count input1))) | ||
(lambda (result) (equal? result output))))) |