github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/strconv/itoa.go (about)

     1  // Copyright 2009 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  package strconv
     6  
     7  // FormatUint returns the string representation of i in the given base,
     8  // for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
     9  // for digit values >= 10.
    10  func FormatUint(i uint64, base int) string {
    11  	_, s := formatBits(nil, i, base, false, false)
    12  	return s
    13  }
    14  
    15  // FormatInt returns the string representation of i in the given base,
    16  // for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
    17  // for digit values >= 10.
    18  func FormatInt(i int64, base int) string {
    19  	_, s := formatBits(nil, uint64(i), base, i < 0, false)
    20  	return s
    21  }
    22  
    23  // Itoa is shorthand for FormatInt(i, 10).
    24  func Itoa(i int) string {
    25  	return FormatInt(int64(i), 10)
    26  }
    27  
    28  // AppendInt appends the string form of the integer i,
    29  // as generated by FormatInt, to dst and returns the extended buffer.
    30  func AppendInt(dst []byte, i int64, base int) []byte {
    31  	dst, _ = formatBits(dst, uint64(i), base, i < 0, true)
    32  	return dst
    33  }
    34  
    35  // AppendUint appends the string form of the unsigned integer i,
    36  // as generated by FormatUint, to dst and returns the extended buffer.
    37  func AppendUint(dst []byte, i uint64, base int) []byte {
    38  	dst, _ = formatBits(dst, i, base, false, true)
    39  	return dst
    40  }
    41  
    42  const (
    43  	digits   = "0123456789abcdefghijklmnopqrstuvwxyz"
    44  	digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
    45  	digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
    46  )
    47  
    48  var shifts = [len(digits) + 1]uint{
    49  	1 << 1: 1,
    50  	1 << 2: 2,
    51  	1 << 3: 3,
    52  	1 << 4: 4,
    53  	1 << 5: 5,
    54  }
    55  
    56  // formatBits computes the string representation of u in the given base.
    57  // If neg is set, u is treated as negative int64 value. If append_ is
    58  // set, the string is appended to dst and the resulting byte slice is
    59  // returned as the first result value; otherwise the string is returned
    60  // as the second result value.
    61  //
    62  func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s string) {
    63  	if base < 2 || base > len(digits) {
    64  		panic("strconv: illegal AppendInt/FormatInt base")
    65  	}
    66  	// 2 <= base && base <= len(digits)
    67  
    68  	var a [64 + 1]byte // +1 for sign of 64bit value in base 2
    69  	i := len(a)
    70  
    71  	if neg {
    72  		u = -u
    73  	}
    74  
    75  	// convert bits
    76  	if base == 10 {
    77  		// common case: use constants for / and % because
    78  		// the compiler can optimize it into a multiply+shift,
    79  		// and unroll loop
    80  		for u >= 100 {
    81  			i -= 2
    82  			q := u / 100
    83  			j := uintptr(u - q*100)
    84  			a[i+1] = digits01[j]
    85  			a[i+0] = digits10[j]
    86  			u = q
    87  		}
    88  		if u >= 10 {
    89  			i--
    90  			q := u / 10
    91  			a[i] = digits[uintptr(u-q*10)]
    92  			u = q
    93  		}
    94  
    95  	} else if s := shifts[base]; s > 0 {
    96  		// base is power of 2: use shifts and masks instead of / and %
    97  		b := uint64(base)
    98  		m := uintptr(b) - 1 // == 1<<s - 1
    99  		for u >= b {
   100  			i--
   101  			a[i] = digits[uintptr(u)&m]
   102  			u >>= s
   103  		}
   104  
   105  	} else {
   106  		// general case
   107  		b := uint64(base)
   108  		for u >= b {
   109  			i--
   110  			a[i] = digits[uintptr(u%b)]
   111  			u /= b
   112  		}
   113  	}
   114  
   115  	// u < base
   116  	i--
   117  	a[i] = digits[uintptr(u)]
   118  
   119  	// add sign, if any
   120  	if neg {
   121  		i--
   122  		a[i] = '-'
   123  	}
   124  
   125  	if append_ {
   126  		d = append(dst, a[i:]...)
   127  		return
   128  	}
   129  	s = string(a[i:])
   130  	return
   131  }