1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file implements nat-to-string conversion functions. 6 7 package big 8 9 import ( 10 "errors" 11 "fmt" 12 "io" 13 "math" 14 "math/bits" 15 "sync" 16 ) 17 18 const digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 19 20 // Note: MaxBase = len(digits), but it must remain an untyped rune constant 21 // for API compatibility. 22 23 // MaxBase is the largest number base accepted for string conversions. 24 const MaxBase = 10 + ('z' - 'a' + 1) + ('Z' - 'A' + 1) 25 const maxBaseSmall = 10 + ('z' - 'a' + 1) 26 27 // maxPow returns (b**n, n) such that b**n is the largest power b**n <= _M. 28 // For instance maxPow(10) == (1e19, 19) for 19 decimal digits in a 64bit Word. 29 // In other words, at most n digits in base b fit into a Word. 30 // TODO(gri) replace this with a table, generated at build time. 31 func maxPow(b Word) (p Word, n int) { 32 p, n = b, 1 // assuming b <= _M 33 for max := _M / b; p <= max; { 34 // p == b**n && p <= max 35 p *= b 36 n++ 37 } 38 // p == b**n && p <= _M 39 return 40 } 41 42 // pow returns x**n for n > 0, and 1 otherwise. 43 func pow(x Word, n int) (p Word) { 44 // n == sum of bi * 2**i, for 0 <= i < imax, and bi is 0 or 1 45 // thus x**n == product of x**(2**i) for all i where bi == 1 46 // (Russian Peasant Method for exponentiation) 47 p = 1 48 for n > 0 { 49 if n&1 != 0 { 50 p *= x 51 } 52 x *= x 53 n >>= 1 54 } 55 return 56 } 57 58 // scan scans the number corresponding to the longest possible prefix 59 // from r representing an unsigned number in a given conversion base. 60 // It returns the corresponding natural number res, the actual base b, 61 // a digit count, and a read or syntax error err, if any. 62 // 63 // number = [ prefix ] mantissa . 64 // prefix = "0" [ "x" | "X" | "b" | "B" ] . 65 // mantissa = digits | digits "." [ digits ] | "." digits . 66 // digits = digit { digit } . 67 // digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" . 68 // 69 // Unless fracOk is set, the base argument must be 0 or a value between 70 // 2 and MaxBase. If fracOk is set, the base argument must be one of 71 // 0, 2, 10, or 16. Providing an invalid base argument leads to a run- 72 // time panic. 73 // 74 // For base 0, the number prefix determines the actual base: A prefix of 75 // ``0x'' or ``0X'' selects base 16; if fracOk is not set, the ``0'' prefix 76 // selects base 8, and a ``0b'' or ``0B'' prefix selects base 2. Otherwise 77 // the selected base is 10 and no prefix is accepted. 78 // 79 // If fracOk is set, an octal prefix is ignored (a leading ``0'' simply 80 // stands for a zero digit), and a period followed by a fractional part 81 // is permitted. The result value is computed as if there were no period 82 // present; and the count value is used to determine the fractional part. 83 // 84 // For bases <= 36, lower and upper case letters are considered the same: 85 // The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35. 86 // For bases > 36, the upper case letters 'A' to 'Z' represent the digit 87 // values 36 to 61. 88 // 89 // A result digit count > 0 corresponds to the number of (non-prefix) digits 90 // parsed. A digit count <= 0 indicates the presence of a period (if fracOk 91 // is set, only), and -count is the number of fractional digits found. 92 // In this case, the actual value of the scanned number is res * b**count. 93 // 94 func (z nat) scan(r io.ByteScanner, base int, fracOk bool) (res nat, b, count int, err error) { 95 // reject illegal bases 96 baseOk := base == 0 || 97 !fracOk && 2 <= base && base <= MaxBase || 98 fracOk && (base == 2 || base == 10 || base == 16) 99 if !baseOk { 100 panic(fmt.Sprintf("illegal number base %d", base)) 101 } 102 103 // one char look-ahead 104 ch, err := r.ReadByte() 105 if err != nil { 106 return 107 } 108 109 // determine actual base 110 b = base 111 if base == 0 { 112 // actual base is 10 unless there's a base prefix 113 b = 10 114 if ch == '0' { 115 count = 1 116 switch ch, err = r.ReadByte(); err { 117 case nil: 118 // possibly one of 0x, 0X, 0b, 0B 119 if !fracOk { 120 b = 8 121 } 122 switch ch { 123 case 'x', 'X': 124 b = 16 125 case 'b', 'B': 126 b = 2 127 } 128 switch b { 129 case 16, 2: 130 count = 0 // prefix is not counted 131 if ch, err = r.ReadByte(); err != nil { 132 // io.EOF is also an error in this case 133 return 134 } 135 case 8: 136 count = 0 // prefix is not counted 137 } 138 case io.EOF: 139 // input is "0" 140 res = z[:0] 141 err = nil 142 return 143 default: 144 // read error 145 return 146 } 147 } 148 } 149 150 // convert string 151 // Algorithm: Collect digits in groups of at most n digits in di 152 // and then use mulAddWW for every such group to add them to the 153 // result. 154 z = z[:0] 155 b1 := Word(b) 156 bn, n := maxPow(b1) // at most n digits in base b1 fit into Word 157 di := Word(0) // 0 <= di < b1**i < bn 158 i := 0 // 0 <= i < n 159 dp := -1 // position of decimal point 160 for { 161 if fracOk && ch == '.' { 162 fracOk = false 163 dp = count 164 // advance 165 if ch, err = r.ReadByte(); err != nil { 166 if err == io.EOF { 167 err = nil 168 break 169 } 170 return 171 } 172 } 173 174 // convert rune into digit value d1 175 var d1 Word 176 switch { 177 case '0' <= ch && ch <= '9': 178 d1 = Word(ch - '0') 179 case 'a' <= ch && ch <= 'z': 180 d1 = Word(ch - 'a' + 10) 181 case 'A' <= ch && ch <= 'Z': 182 if b <= maxBaseSmall { 183 d1 = Word(ch - 'A' + 10) 184 } else { 185 d1 = Word(ch - 'A' + maxBaseSmall) 186 } 187 default: 188 d1 = MaxBase + 1 189 } 190 if d1 >= b1 { 191 r.UnreadByte() // ch does not belong to number anymore 192 break 193 } 194 count++ 195 196 // collect d1 in di 197 di = di*b1 + d1 198 i++ 199 200 // if di is "full", add it to the result 201 if i == n { 202 z = z.mulAddWW(z, bn, di) 203 di = 0 204 i = 0 205 } 206 207 // advance 208 if ch, err = r.ReadByte(); err != nil { 209 if err == io.EOF { 210 err = nil 211 break 212 } 213 return 214 } 215 } 216 217 if count == 0 { 218 // no digits found 219 switch { 220 case base == 0 && b == 8: 221 // there was only the octal prefix 0 (possibly followed by digits > 7); 222 // count as one digit and return base 10, not 8 223 count = 1 224 b = 10 225 case base != 0 || b != 8: 226 // there was neither a mantissa digit nor the octal prefix 0 227 err = errors.New("syntax error scanning number") 228 } 229 return 230 } 231 // count > 0 232 233 // add remaining digits to result 234 if i > 0 { 235 z = z.mulAddWW(z, pow(b1, i), di) 236 } 237 res = z.norm() 238 239 // adjust for fraction, if any 240 if dp >= 0 { 241 // 0 <= dp <= count > 0 242 count = dp - count 243 } 244 245 return 246 } 247 248 // utoa converts x to an ASCII representation in the given base; 249 // base must be between 2 and MaxBase, inclusive. 250 func (x nat) utoa(base int) []byte { 251 return x.itoa(false, base) 252 } 253 254 // itoa is like utoa but it prepends a '-' if neg && x != 0. 255 func (x nat) itoa(neg bool, base int) []byte { 256 if base < 2 || base > MaxBase { 257 panic("invalid base") 258 } 259 260 // x == 0 261 if len(x) == 0 { 262 return []byte("0") 263 } 264 // len(x) > 0 265 266 // allocate buffer for conversion 267 i := int(float64(x.bitLen())/math.Log2(float64(base))) + 1 // off by 1 at most 268 if neg { 269 i++ 270 } 271 s := make([]byte, i) 272 273 // convert power of two and non power of two bases separately 274 if b := Word(base); b == b&-b { 275 // shift is base b digit size in bits 276 shift := uint(bits.TrailingZeros(uint(b))) // shift > 0 because b >= 2 277 mask := Word(1<<shift - 1) 278 w := x[0] // current word 279 nbits := uint(_W) // number of unprocessed bits in w 280 281 // convert less-significant words (include leading zeros) 282 for k := 1; k < len(x); k++ { 283 // convert full digits 284 for nbits >= shift { 285 i-- 286 s[i] = digits[w&mask] 287 w >>= shift 288 nbits -= shift 289 } 290 291 // convert any partial leading digit and advance to next word 292 if nbits == 0 { 293 // no partial digit remaining, just advance 294 w = x[k] 295 nbits = _W 296 } else { 297 // partial digit in current word w (== x[k-1]) and next word x[k] 298 w |= x[k] << nbits 299 i-- 300 s[i] = digits[w&mask] 301 302 // advance 303 w = x[k] >> (shift - nbits) 304 nbits = _W - (shift - nbits) 305 } 306 } 307 308 // convert digits of most-significant word w (omit leading zeros) 309 for w != 0 { 310 i-- 311 s[i] = digits[w&mask] 312 w >>= shift 313 } 314 315 } else { 316 bb, ndigits := maxPow(b) 317 318 // construct table of successive squares of bb*leafSize to use in subdivisions 319 // result (table != nil) <=> (len(x) > leafSize > 0) 320 table := divisors(len(x), b, ndigits, bb) 321 322 // preserve x, create local copy for use by convertWords 323 q := nat(nil).set(x) 324 325 // convert q to string s in base b 326 q.convertWords(s, b, ndigits, bb, table) 327 328 // strip leading zeros 329 // (x != 0; thus s must contain at least one non-zero digit 330 // and the loop will terminate) 331 i = 0 332 for s[i] == '0' { 333 i++ 334 } 335 } 336 337 if neg { 338 i-- 339 s[i] = '-' 340 } 341 342 return s[i:] 343 } 344 345 // Convert words of q to base b digits in s. If q is large, it is recursively "split in half" 346 // by nat/nat division using tabulated divisors. Otherwise, it is converted iteratively using 347 // repeated nat/Word division. 348 // 349 // The iterative method processes n Words by n divW() calls, each of which visits every Word in the 350 // incrementally shortened q for a total of n + (n-1) + (n-2) ... + 2 + 1, or n(n+1)/2 divW()'s. 351 // Recursive conversion divides q by its approximate square root, yielding two parts, each half 352 // the size of q. Using the iterative method on both halves means 2 * (n/2)(n/2 + 1)/2 divW()'s 353 // plus the expensive long div(). Asymptotically, the ratio is favorable at 1/2 the divW()'s, and 354 // is made better by splitting the subblocks recursively. Best is to split blocks until one more 355 // split would take longer (because of the nat/nat div()) than the twice as many divW()'s of the 356 // iterative approach. This threshold is represented by leafSize. Benchmarking of leafSize in the 357 // range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and 358 // ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for 359 // specific hardware. 360 // 361 func (q nat) convertWords(s []byte, b Word, ndigits int, bb Word, table []divisor) { 362 // split larger blocks recursively 363 if table != nil { 364 // len(q) > leafSize > 0 365 var r nat 366 index := len(table) - 1 367 for len(q) > leafSize { 368 // find divisor close to sqrt(q) if possible, but in any case < q 369 maxLength := q.bitLen() // ~= log2 q, or at of least largest possible q of this bit length 370 minLength := maxLength >> 1 // ~= log2 sqrt(q) 371 for index > 0 && table[index-1].nbits > minLength { 372 index-- // desired 373 } 374 if table[index].nbits >= maxLength && table[index].bbb.cmp(q) >= 0 { 375 index-- 376 if index < 0 { 377 panic("internal inconsistency") 378 } 379 } 380 381 // split q into the two digit number (q'*bbb + r) to form independent subblocks 382 q, r = q.div(r, q, table[index].bbb) 383 384 // convert subblocks and collect results in s[:h] and s[h:] 385 h := len(s) - table[index].ndigits 386 r.convertWords(s[h:], b, ndigits, bb, table[0:index]) 387 s = s[:h] // == q.convertWords(s, b, ndigits, bb, table[0:index+1]) 388 } 389 } 390 391 // having split any large blocks now process the remaining (small) block iteratively 392 i := len(s) 393 var r Word 394 if b == 10 { 395 // hard-coding for 10 here speeds this up by 1.25x (allows for / and % by constants) 396 for len(q) > 0 { 397 // extract least significant, base bb "digit" 398 q, r = q.divW(q, bb) 399 for j := 0; j < ndigits && i > 0; j++ { 400 i-- 401 // avoid % computation since r%10 == r - int(r/10)*10; 402 // this appears to be faster for BenchmarkString10000Base10 403 // and smaller strings (but a bit slower for larger ones) 404 t := r / 10 405 s[i] = '0' + byte(r-t*10) 406 r = t 407 } 408 } 409 } else { 410 for len(q) > 0 { 411 // extract least significant, base bb "digit" 412 q, r = q.divW(q, bb) 413 for j := 0; j < ndigits && i > 0; j++ { 414 i-- 415 s[i] = digits[r%b] 416 r /= b 417 } 418 } 419 } 420 421 // prepend high-order zeros 422 for i > 0 { // while need more leading zeros 423 i-- 424 s[i] = '0' 425 } 426 } 427 428 // Split blocks greater than leafSize Words (or set to 0 to disable recursive conversion) 429 // Benchmark and configure leafSize using: go test -bench="Leaf" 430 // 8 and 16 effective on 3.0 GHz Xeon "Clovertown" CPU (128 byte cache lines) 431 // 8 and 16 effective on 2.66 GHz Core 2 Duo "Penryn" CPU 432 var leafSize int = 8 // number of Word-size binary values treat as a monolithic block 433 434 type divisor struct { 435 bbb nat // divisor 436 nbits int // bit length of divisor (discounting leading zeros) ~= log2(bbb) 437 ndigits int // digit length of divisor in terms of output base digits 438 } 439 440 var cacheBase10 struct { 441 sync.Mutex 442 table [64]divisor // cached divisors for base 10 443 } 444 445 // expWW computes x**y 446 func (z nat) expWW(x, y Word) nat { 447 return z.expNN(nat(nil).setWord(x), nat(nil).setWord(y), nil) 448 } 449 450 // construct table of powers of bb*leafSize to use in subdivisions 451 func divisors(m int, b Word, ndigits int, bb Word) []divisor { 452 // only compute table when recursive conversion is enabled and x is large 453 if leafSize == 0 || m <= leafSize { 454 return nil 455 } 456 457 // determine k where (bb**leafSize)**(2**k) >= sqrt(x) 458 k := 1 459 for words := leafSize; words < m>>1 && k < len(cacheBase10.table); words <<= 1 { 460 k++ 461 } 462 463 // reuse and extend existing table of divisors or create new table as appropriate 464 var table []divisor // for b == 10, table overlaps with cacheBase10.table 465 if b == 10 { 466 cacheBase10.Lock() 467 table = cacheBase10.table[0:k] // reuse old table for this conversion 468 } else { 469 table = make([]divisor, k) // create new table for this conversion 470 } 471 472 // extend table 473 if table[k-1].ndigits == 0 { 474 // add new entries as needed 475 var larger nat 476 for i := 0; i < k; i++ { 477 if table[i].ndigits == 0 { 478 if i == 0 { 479 table[0].bbb = nat(nil).expWW(bb, Word(leafSize)) 480 table[0].ndigits = ndigits * leafSize 481 } else { 482 table[i].bbb = nat(nil).sqr(table[i-1].bbb) 483 table[i].ndigits = 2 * table[i-1].ndigits 484 } 485 486 // optimization: exploit aggregated extra bits in macro blocks 487 larger = nat(nil).set(table[i].bbb) 488 for mulAddVWW(larger, larger, b, 0) == 0 { 489 table[i].bbb = table[i].bbb.set(larger) 490 table[i].ndigits++ 491 } 492 493 table[i].nbits = table[i].bbb.bitLen() 494 } 495 } 496 } 497 498 if b == 10 { 499 cacheBase10.Unlock() 500 } 501 502 return table 503 } 504