// 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 strconvimportconst fastSmalls = true// enable fast path for small integers// 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 {iffastSmalls && < nSmalls && == 10 {returnsmall(int()) } , := 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 {iffastSmalls && 0 <= && < nSmalls && == 10 {returnsmall(int()) } , := 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 {iffastSmalls && 0 <= && < nSmalls && == 10 {returnappend(, small(int())...) } , _ = formatBits(, uint64(), , < 0, true)return}// 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 {iffastSmalls && < nSmalls && == 10 {returnappend(, small(int())...) } , _ = formatBits(, , , false, true)return}// small returns the string for an i with 0 <= i < nSmalls.func small( int) string {if < 10 {returndigits[ : +1] }returnsmallsString[*2 : *2+2]}const nSmalls = 100const smallsString = "00010203040506070809" +"10111213141516171819" +"20212223242526272829" +"30313233343536373839" +"40414243444546474849" +"50515253545556575859" +"60616263646566676869" +"70717273747576777879" +"80818283848586878889" +"90919293949596979899"const host32bit = ^uint(0)>>32 == 0const 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.func formatBits( []byte, uint64, int, , bool) ( []byte, string) {if < 2 || > 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.if == 10 {// common case: use constants for / because // the compiler can optimize it into a multiply+shiftifhost32bit {// convert the lower digits using 32bit operationsfor >= 1e9 {// 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. := / 1e9 := uint( - *1e9) // u % 1e9 fits into a uintfor := 4; > 0; -- { := % 100 * 2 /= 100 -= 2 [+1] = smallsString[+1] [+0] = smallsString[+0] }// us < 10, since it contains the last digit // from the initial 9-digit us. -- [] = smallsString[*2+1] = }// u < 1e9 }// u guaranteed to fit into a uint := uint()for >= 100 { := % 100 * 2 /= 100 -= 2 [+1] = smallsString[+1] [+0] = smallsString[+0] }// us < 100 := * 2 -- [] = smallsString[+1]if >= 10 { -- [] = smallsString[] } } elseifisPowerOfTwo() {// Use shifts and masks instead of / and %. // Base is a power of 2 and 2 <= base <= len(digits) where len(digits) is 36. // The largest power of 2 below or equal to 36 is 32, which is 1 << 5; // i.e., the largest possible shift count is 5. By &-ind that value with // the constant 7 we tell the compiler that the shift count is always // less than 8 which is smaller than any register width. This allows // the compiler to generate better code for the shift operation. := uint(bits.TrailingZeros(uint())) & 7 := 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}
The pages are generated with Goldsv0.6.9-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 @Go100and1 (reachable from the left QR code) to get the latest news of Golds.