// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package strconvimport// FormatUint returns the string representation of i in the given base,// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'// for digit values >= 10.func ( uint64, int) string {if == 10 {if < nSmalls {returnsmall(int()) }var [24]byte := formatBase10([:], )returnstring([:]) } , := formatBits(nil, , , false, false)return}// FormatInt returns the string representation of i in the given base,// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'// for digit values >= 10.func ( int64, int) string {if == 10 {if0 <= && < nSmalls {returnsmall(int()) }var [24]byte := uint64()if < 0 { = - } := formatBase10([:], )if < 0 { -- [] = '-' }returnstring([:]) } , := formatBits(nil, uint64(), , < 0, false)return}// Itoa is equivalent to [FormatInt](int64(i), 10).func ( int) string {returnFormatInt(int64(), 10)}// AppendInt appends the string form of the integer i,// as generated by [FormatInt], to dst and returns the extended buffer.func ( []byte, int64, int) []byte { := uint64()if < 0 { = append(, '-') = - }returnAppendUint(, , )}// AppendUint appends the string form of the unsigned integer i,// as generated by [FormatUint], to dst and returns the extended buffer.func ( []byte, uint64, int) []byte {if == 10 {if < nSmalls {returnappend(, small(int())...) }var [24]byte := formatBase10([:], )returnappend(, [:]...) } , _ = formatBits(, , , false, true)return}const digits = "0123456789abcdefghijklmnopqrstuvwxyz"// formatBits computes the string representation of u in the given base.// If neg is set, u is treated as negative int64 value. If append_ is// set, the string is appended to dst and the resulting byte slice is// returned as the first result value; otherwise the string is returned// as the second result value.// The caller is expected to have handled base 10 separately for speed.func formatBits( []byte, uint64, int, , bool) ( []byte, string) {if < 2 || == 10 || > len(digits) {panic("strconv: illegal AppendInt/FormatInt base") }// 2 <= base && base <= len(digits)var [64 + 1]byte// +1 for sign of 64bit value in base 2 := len()if { = - }// convert bits // We use uint values where we can because those will // fit into a single register even on a 32bit machine.ifisPowerOfTwo() {// Use shifts and masks instead of / and %. := uint(bits.TrailingZeros(uint())) := uint64() := uint() - 1// == 1<<shift - 1for >= { -- [] = digits[uint()&] >>= }// u < base -- [] = digits[uint()] } else {// general case := uint64()for >= { --// Avoid using r = a%b in addition to q = a/b // since 64bit division and modulo operations // are calculated by runtime functions on 32bit machines. := / [] = digits[uint(-*)] = }// u < base -- [] = digits[uint()] }// add sign, if anyif { -- [] = '-' }if { = append(, [:]...)return } = string([:])return}func isPowerOfTwo( int) bool {return &(-1) == 0}const nSmalls = 100// smalls is the formatting of 00..99 concatenated.// It is then padded out with 56 x's to 256 bytes,// so that smalls[x&0xFF] has no bounds check.const smalls = "00010203040506070809" +"10111213141516171819" +"20212223242526272829" +"30313233343536373839" +"40414243444546474849" +"50515253545556575859" +"60616263646566676869" +"70717273747576777879" +"80818283848586878889" +"90919293949596979899"const host64bit = ^uint(0)>>32 != 0// small returns the string for an i with 0 <= i < nSmalls.func small( int) string {if < 10 {returndigits[ : +1] }returnsmalls[*2 : *2+2]}// RuntimeFormatBase10 formats u into the tail of a// and returns the offset to the first byte written to a.// It is only for use by package runtime.// Other packages should use AppendUint.func ( []byte, uint64) int {returnformatBase10(, )}// formatBase10 formats the decimal representation of u into the tail of a// and returns the offset of the first byte written to a. That is, after//// i := formatBase10(a, u)//// the decimal representation is in a[i:].func formatBase10( []byte, uint64) int {// Split into 9-digit chunks that fit in uint32s // and convert each chunk using uint32 math instead of uint64 math. // The obvious way to write the outer loop is "for u >= 1e9", but most numbers are small, // so the setup for the comparison u >= 1e9 is usually pure overhead. // Instead, we approximate it by u>>29 != 0, which is usually faster and good enough. := len()for (host64bit && >>29 != 0) || (!host64bit && uint32()>>29|uint32(>>32) != 0) {varuint32 , = /1e9, uint32(%1e9)// Convert 9 digits.forrange4 {varuint32 , = /100, (%100)*2 -= 2 [+0], [+1] = smalls[+0], smalls[+1] } -- [] = smalls[*2+1]// If we'd been using u >= 1e9 then we would be guaranteed that u/1e9 > 0, // but since we used u>>29 != 0, u/1e9 might be 0, so we might be done. // (If u is now 0, then at the start we had 2²⁹ ≤ u < 10⁹, so it was still correct // to write 9 digits; we have not accidentally written any leading zeros.)if == 0 {return } }// Convert final chunk, at most 8 digits. := uint32()for >= 100 {varuint32 , = /100, (%100)*2 -= 2 [+0], [+1] = smalls[+0], smalls[+1] } -- := * 2 [] = smalls[+1]if >= 10 { -- [] = smalls[+0] }return}
The pages are generated with Goldsv0.8.3-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.