对Golang10进制转16进制的几种方法做了一些总结,一切尽在代码中:
func main() {
// 以下为10进制转16进制的几种方式:
//1 手撸
hex := toHex(di)
//2 内置的string工具包
hex1 := strconv.FormatInt(int64(di), 16)
//3 format 提供的方法
hex2 := fmt.Sprintf("%x", di)
}
如果仅是找工具的看客,看到这里就可以止步了,以下内容纯属自娱:
/**
循环右移4位(一个16进制数),取下标,拼接成字符串,
右移过程中,先取低位,因此拼接过程需要对结果做反转。
给出的两种实现区别仅在于反转的方式不同:
1.先循环一次,找到转换后16进制数的长度,拼接时从后往前。(长得有点难看)
2.直接用切片间的 append 反向拼接(每次构建新的切片,占用较多空间)
*/
// scheme 1:
func toHex0(di int) string {
index := 0
var o = di
for o >= 16 {
index++
o >>= 4
}
ret := make([]byte, index+1)
var i = 0
digits := "0123456789abcdefx"
for di >= 16 {
ret[index-i] = digits[di&0xF]
i++
di >>= 4
}
ret[0] = digits[di&0xF]
return string(ret)
}
// scheme 2:
func toHex(di int) string {
ret := make([]byte, 0)
digits := "0123456789abcdefx"
for di >= 16 {
//从低位往高位取,直接使用切片append 单个元素,结果是倒序的
temp := []byte{digits[di&0xF]}
temp = append(temp, ret...)
ret = temp
di >>= 4
}
// 最高位在循环外,单独取
temp := []byte{digits[di&0xF]}
return string(append(temp, ret...))
}
基于以上原理,可以写一个32进制下的通用转换:
func toBelow32(di int, base int) string {
upperstr := "0123456789abcdefghijklmnopqrstuv"
substr := upperstr[0:base]
ret := make([]byte, 0)
mol := base - 1
mov := math.Log2(float64(base))
for di >= base {
temp := []byte{substr[di&mol]}
temp = append(temp, ret...)
ret = temp
di >>= int(mov)
}
temp := []byte{substr[di&mol]}
return string(append(temp, ret...))
}
//eg:toBelow32(anynum,16)
注意:该方法基于循环右移实现,只适用10到2的n次幂(2,4,8,16,32)进制的转换。
补充:意外发现golang math 包下提供了log函数,方法1 可以更优雅的实现:
func toHex0(di int) string {
index := int(math.Log2(float64(math.Log2(float64(di)))))
ret := make([]byte, index+1)
var i = 0
digits := "0123456789abcdefx"
for di >= 16 {
ret[index-i] = digits[di&0xF]
i++
di >>= 4
}
ret[0] = digits[di&0xF]
return string(ret)
}