github.com/iEvan-lhr/exciting-tool@v0.0.0-20230504054234-8e983f73cdd2/charset.go (about) 1 package tools 2 3 import ( 4 "math/bits" 5 ) 6 7 const nSmalls = 100 8 9 const smallsString = "00010203040506070809" + 10 "10111213141516171819" + 11 "20212223242526272829" + 12 "30313233343536373839" + 13 "40414243444546474849" + 14 "50515253545556575859" + 15 "60616263646566676869" + 16 "70717273747576777879" + 17 "80818283848586878889" + 18 "90919293949596979899" 19 20 const host32bit = ^uint(0)>>32 == 0 21 22 const fastSmalls = true // enable fast path for small integers 23 24 const digits = "0123456789abcdefghijklmnopqrstuvwxyz" 25 26 // Float 此结构体用来进行自定义的Str拼接类型转换 27 type Float struct { 28 Number any 29 Fmt byte 30 Pre int 31 } 32 33 // formatInt returns the string representation of i in the given base, 34 // for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z' 35 // for digit values >= 10. 36 func formatInt(i int64, base int, byt *[]byte) int { 37 if fastSmalls && 0 <= i && i < nSmalls && base == 10 { 38 if i < 10 { 39 *byt = append(*byt, digits[i : i+1][0]) 40 return 1 41 } else { 42 *byt = append(*byt, []byte(smallsString[i*2:i*2+2])...) 43 return 2 44 } 45 46 } 47 return formatBits(byt, uint64(i), base, i < 0) 48 } 49 50 // appendInt is quick append int to String 51 func appendInt(i int, byt *[]byte) int { 52 return formatInt(int64(i), 10, byt) 53 } 54 55 func formatBits(dst *[]byte, u uint64, base int, neg bool) int { 56 if base < 2 || base > len(digits) { 57 panic("strconv: illegal AppendInt/FormatInt base") 58 } 59 // 2 <= base && base <= len(digits) 60 61 var a [64 + 1]byte // +1 for sign of 64bit value in base 2 62 i := len(a) 63 64 if neg { 65 u = -u 66 } 67 68 // convert bits 69 // We use uint values where we can because those will 70 // fit into a single register even on a 32bit machine. 71 if base == 10 { 72 // common case: use constants for / because 73 // the compiler can optimize it into a multiply+shift 74 75 if host32bit { 76 // convert the lower digits using 32bit operations 77 for u >= 1e9 { 78 // Avoid using r = a%b in addition to q = a/b 79 // since 64bit division and modulo operations 80 // are calculated by runtime functions on 32bit machines. 81 q := u / 1e9 82 us := uint(u - q*1e9) // u % 1e9 fits into a uint 83 for j := 4; j > 0; j-- { 84 is := us % 100 * 2 85 us /= 100 86 i -= 2 87 a[i+1] = smallsString[is+1] 88 a[i+0] = smallsString[is+0] 89 } 90 91 // us < 10, since it contains the last digit 92 // from the initial 9-digit us. 93 i-- 94 a[i] = smallsString[us*2+1] 95 96 u = q 97 } 98 // u < 1e9 99 } 100 101 // u guaranteed to fit into a uint 102 us := uint(u) 103 for us >= 100 { 104 is := us % 100 * 2 105 us /= 100 106 i -= 2 107 a[i+1] = smallsString[is+1] 108 a[i+0] = smallsString[is+0] 109 } 110 111 // us < 100 112 is := us * 2 113 i-- 114 a[i] = smallsString[is+1] 115 if us >= 10 { 116 i-- 117 a[i] = smallsString[is] 118 } 119 120 } else if isPowerOfTwo(base) { 121 // Use shifts and masks instead of / and %. 122 // Base is a power of 2 and 2 <= base <= len(digits) where len(digits) is 36. 123 // The largest power of 2 below or equal to 36 is 32, which is 1 << 5; 124 // i.e., the largest possible shift count is 5. By &-ind that value with 125 // the constant 7 we tell the compiler that the shift count is always 126 // less than 8 which is smaller than any register width. This allows 127 // the compiler to generate better code for the shift operation. 128 shift := uint(bits.TrailingZeros(uint(base))) & 7 129 b := uint64(base) 130 m := uint(base) - 1 // == 1<<shift - 1 131 for u >= b { 132 i-- 133 a[i] = digits[uint(u)&m] 134 u >>= shift 135 } 136 // u < base 137 i-- 138 a[i] = digits[uint(u)] 139 } else { 140 // general case 141 b := uint64(base) 142 for u >= b { 143 i-- 144 // Avoid using r = a%b in addition to q = a/b 145 // since 64bit division and modulo operations 146 // are calculated by runtime functions on 32bit machines. 147 q := u / b 148 a[i] = digits[uint(u-q*b)] 149 u = q 150 } 151 // u < base 152 i-- 153 a[i] = digits[uint(u)] 154 } 155 156 // add sign, if any 157 if neg { 158 i-- 159 a[i] = '-' 160 } 161 *dst = append(*dst, a[i:]...) 162 return len(a[i:]) 163 } 164 165 func isPowerOfTwo(x int) bool { 166 return x&(x-1) == 0 167 } 168 169 // AppendUint appends the string form of the unsigned integer i, 170 // as generated by FormatUint, to dst and returns the extended buffer. 171 func appendUint64(i uint64, byt *[]byte) int { 172 return formatBits(byt, i, 10, i < 0) 173 }