Home | History | Annotate | Download | only in big
      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