Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1226)

Side by Side Diff: tools/generate-ten-powers.scm

Issue 619005: Fast algorithm for double->string conversion. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 ;; Copyright 2010 the V8 project authors. All rights reserved.
2 ;; Redistribution and use in source and binary forms, with or without
3 ;; modification, are permitted provided that the following conditions are
4 ;; met:
5 ;;
6 ;; * Redistributions of source code must retain the above copyright
7 ;; notice, this list of conditions and the following disclaimer.
8 ;; * Redistributions in binary form must reproduce the above
9 ;; copyright notice, this list of conditions and the following
10 ;; disclaimer in the documentation and/or other materials provided
11 ;; with the distribution.
12 ;; * Neither the name of Google Inc. nor the names of its
13 ;; contributors may be used to endorse or promote products derived
14 ;; from this software without specific prior written permission.
15 ;;
16 ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 ;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 ;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 ;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 ;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 ;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 ;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 ;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 ;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 ;; Generate approximations of 10^k.
29 ;; Requires Bigloo to compile:
30 ;; bigloo -static-bigloo -o generate-ten-powers generate-ten-powers.scm
31
32 (module gen-ten-powers
33 (static (class Cached-Fast
34 v::bignum
35 e::bint
36 exact?::bool))
37 (main my-main))
38
39
40 ;;----------------bignum shifts -----------------------------------------------
41 (define (bit-lshbx::bignum x::bignum by::bint)
42 (if (<fx by 0)
43 #z0
44 (*bx x (exptbx #z2 (fixnum->bignum by)))))
45
46 (define (bit-rshbx::bignum x::bignum by::bint)
47 (if (<fx by 0)
48 #z0
49 (/bx x (exptbx #z2 (fixnum->bignum by)))))
50
51 ;;----------------the actual power generation -------------------------------
52
53 ;; e should be an indication. it might be too small.
54 (define (round-n-cut n e nb-bits)
55 (define max-container (- (bit-lshbx #z1 nb-bits) 1))
56 (define (round n)
57 (case *round*
58 ((down) n)
59 ((up)
60 (+bx n
61 ;; with the -1 it will only round up if the cut off part is
62 ;; non-zero
63 (-bx (bit-lshbx #z1
64 (-fx (+fx e nb-bits) 1))
65 #z1)))
66 ((round)
67 (+bx n
68 (bit-lshbx #z1
69 (-fx (+fx e nb-bits) 2))))))
70 (let* ((shift (-fx (+fx e nb-bits) 1))
71 (cut (bit-rshbx (round n) shift))
72 (exact? (=bx n (bit-lshbx cut shift))))
73 (if (<=bx cut max-container)
74 (values cut e exact?)
75 (round-n-cut n (+fx e 1) nb-bits))))
76
77 (define (rounded-/bx x y)
78 (case *round*
79 ((down) (/bx x y))
80 ((up) (+bx (/bx x y) #z1))
81 ((round) (let ((tmp (/bx (*bx #z2 x) y)))
82 (if (zerobx? (remainderbx tmp #z2))
83 (/bx tmp #z2)
84 (+bx (/bx tmp #z2) #z1))))))
85
86 (define (generate-powers from to mantissa-size)
87 (let* ((nb-bits mantissa-size)
88 (offset (- from))
89 (nb-elements (+ (- from) to 1))
90 (vec (make-vector nb-elements))
91 (max-container (- (bit-lshbx #z1 nb-bits) 1)))
92 ;; the negative ones. 10^-1, 10^-2, etc.
93 ;; We already know, that we can't be exact, so exact? will always be #f.
94 ;; Basically we will have a ten^i that we will *10 at each iteration. We
95 ;; want to create the matissa of 1/ten^i. However the mantissa must be
96 ;; normalized (start with a 1). -> we have to shift the number.
97 ;; We shift by multiplying with two^e. -> We encode two^e*(1/ten^i) ==
98 ;; two^e/ten^i.
99 (let loop ((i 1)
100 (ten^i #z10)
101 (two^e #z1)
102 (e 0))
103 (unless (< (- i) from)
104 (if (>bx (/bx (*bx #z2 two^e) ten^i) max-container)
105 ;; another shift would make the number too big. We are
106 ;; hence normalized now.
107 (begin
108 (vector-set! vec (-fx offset i)
109 (instantiate::Cached-Fast
110 (v (rounded-/bx two^e ten^i))
111 (e (negfx e))
112 (exact? #f)))
113 (loop (+fx i 1) (*bx ten^i #z10) two^e e))
114 (loop i ten^i (bit-lshbx two^e 1) (+fx e 1)))))
115 ;; the positive ones 10^0, 10^1, etc.
116 ;; start with 1.0. mantissa: 10...0 (1 followed by nb-bits-1 bits)
117 ;; -> e = -(nb-bits-1)
118 ;; exact? is true when the container can still hold the complete 10^i
119 (let loop ((i 0)
120 (n (bit-lshbx #z1 (-fx nb-bits 1)))
121 (e (-fx 1 nb-bits)))
122 (when (<= i to)
123 (receive (cut e exact?)
124 (round-n-cut n e nb-bits)
125 (vector-set! vec (+fx i offset)
126 (instantiate::Cached-Fast
127 (v cut)
128 (e e)
129 (exact? exact?)))
130 (loop (+fx i 1) (*bx n #z10) e))))
131 vec))
132
133 (define (print-c powers from to struct-type
134 cache-name max-distance-name offset-name macro64)
135 (define (display-power power k)
136 (with-access::Cached-Fast power (v e exact?)
137 (let ((tmp-p (open-output-string)))
138 ;; really hackish way of getting the digits
139 (display (format "~x" v) tmp-p)
140 (let ((str (close-output-port tmp-p)))
141 (printf " {~a(0x~a, ~a), ~a, ~a},\n"
142 macro64
143 (substring str 0 8)
144 (substring str 8 16)
145 e
146 k)))))
147 (define (print-powers-reduced n)
148 (print "static const " struct-type " " cache-name
149 "(" n ")"
150 "[] = {")
151 (let loop ((i 0)
152 (nb-elements 0)
153 (last-e 0)
154 (max-distance 0))
155 (cond
156 ((>= i (vector-length powers))
157 (print " };")
158 (print "static const int " max-distance-name "(" n ") = "
159 max-distance ";")
160 (print "// nb elements (" n "): " nb-elements))
161 (else
162 (let* ((power (vector-ref powers i))
163 (e (Cached-Fast-e power)))
164 (display-power power (+ i from))
165 (loop (+ i n)
166 (+ nb-elements 1)
167 e
168 (cond
169 ((=fx i 0) max-distance)
170 ((> (- e last-e) max-distance) (- e last-e))
171 (else max-distance))))))))
172 (print "// ------------ GENERATED FILE ----------------")
173 (print "// command used:")
174 (print "// "
175 (apply string-append (map (lambda (str)
176 (string-append " " str))
177 *main-args*))
178 " // NOLINT")
179 (print)
180 (print-powers-reduced 1)
181 (print-powers-reduced 2)
182 (print-powers-reduced 3)
183 (print-powers-reduced 4)
184 (print-powers-reduced 5)
185 (print-powers-reduced 6)
186 (print-powers-reduced 7)
187 (print-powers-reduced 8)
188 (print-powers-reduced 9)
189 (print-powers-reduced 10)
190 (print-powers-reduced 11)
191 (print-powers-reduced 12)
192 (print-powers-reduced 13)
193 (print-powers-reduced 14)
194 (print-powers-reduced 15)
195 (print-powers-reduced 16)
196 (print-powers-reduced 17)
197 (print-powers-reduced 18)
198 (print-powers-reduced 19)
199 (print-powers-reduced 20)
200 (print "static const int GRISU_CACHE_OFFSET = " (- from) ";"))
201
202 ;;----------------main --------------------------------------------------------
203 (define *main-args* #f)
204 (define *mantissa-size* #f)
205 (define *dest* #f)
206 (define *round* #f)
207 (define *from* #f)
208 (define *to* #f)
209
210 (define (my-main args)
211 (set! *main-args* args)
212 (args-parse (cdr args)
213 (section "Help")
214 (("?") (args-parse-usage #f))
215 ((("-h" "--help") (help "?, -h, --help" "This help message"))
216 (args-parse-usage #f))
217 (section "Misc")
218 (("-o" ?file (help "The output file"))
219 (set! *dest* file))
220 (("--mantissa-size" ?size (help "Container-size in bits"))
221 (set! *mantissa-size* (string->number size)))
222 (("--round" ?direction (help "Round bignums (down, round or up)"))
223 (set! *round* (string->symbol direction)))
224 (("--from" ?from (help "start at 10^from"))
225 (set! *from* (string->number from)))
226 (("--to" ?to (help "go up to 10^to"))
227 (set! *to* (string->number to)))
228 (else
229 (print "Illegal argument `" else "'. Usage:")
230 (args-parse-usage #f)))
231 (when (not *from*)
232 (error "generate-ten-powers"
233 "Missing from"
234 #f))
235 (when (not *to*)
236 (error "generate-ten-powers"
237 "Missing to"
238 #f))
239 (when (not *mantissa-size*)
240 (error "generate-ten-powers"
241 "Missing mantissa size"
242 #f))
243 (when (not (memv *round* '(up down round)))
244 (error "generate-ten-powers"
245 "Missing round-method"
246 *round*))
247
248 (let ((dividers (generate-powers *from* *to* *mantissa-size*))
249 (p (if (not *dest*)
250 (current-output-port)
251 (open-output-file *dest*))))
252 (unwind-protect
253 (with-output-to-port p
254 (lambda ()
255 (print-c dividers *from* *to*
256 "GRISU_CACHE_STRUCT" "GRISU_CACHE_NAME"
257 "GRISU_CACHE_MAX_DISTANCE" "GRISU_CACHE_OFFSET"
258 "GRISU_UINT64_C"
259 )))
260 (if *dest*
261 (close-output-port p)))))
OLDNEW
« src/cached_powers.h ('K') | « test/cctest/test-grisu3.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698