Go语言实现十进制、二进制、八进制、十六进制的转换

Go语言实现多进制转换
 

除了使用strconv.ParseInt()和strconv.FormatInt()来进行进制间的转换,我们还可以尝试通过数学运算来自己实现


package convert

import (
   "fmt"
   "log"
   "math"
   "strconv"
   "strings"
)

// Decimal to binary
func DecBin(n int64) string {
   if n < 0 {
      log.Println("Decimal to binary error: the argument must be greater than zero.")
      return ""
   }
   if n == 0 {
      return "0"
   }
   s := ""
   for q := n; q > 0; q = q / 2 {
      m := q % 2
      s = fmt.Sprintf("%v%v", m, s)
   }
   return s
}

// Decimal to octal
func DecOct(d int64) int64 {
   if d == 0 {
      return 0
   }
   if d < 0 {
      log.Println("Decimal to octal error: the argument must be greater than zero.")
      return -1
   }
   s := 
<think>我们首先需要明确用户的问题:在Go语言中,将字符串形式的数字转换八进制十六进制十进制,并了解它们之间的区别。 根据引用[2]和引用[4]的内容,我们知道数字在内存中是以二进制形式存储的,而其他进制的数字在存储前必须转换二进制。输出时,我们可以将二进制数字转换为任意进制的字符串表示形式。 在Go语言中,我们可以使用`strconv`包中的函数来实现字符串数字到不同进制的转换。同时,我们还需要注意不同进制表示法的前缀(如八进制的前缀是0,十六进制的前缀是0x)以及转换时的基数(base)。 步骤: 1. 将字符串解析为整数(十进制八进制十六进制等)时,我们需要指定基数(0, 2, 8, 10, 16)。其中,基数0表示让函数根据字符串的前缀自动判断(0开头的为八进制,0x开头的为十六进制,否则为十进制)。 2. 将整数格式化为不同进制的字符串表示。 具体方法: - 使用`strconv.ParseInt`函数将字符串解析为整数(int64类型)。 - 使用`strconv.FormatInt`函数将整数格式化为指定进制的字符串。 另外,对于无符号整数,可以使用`strconv.ParseUint`和`strconv.FormatUint`。 我们还需要注意,如果字符串表示的数字有前缀(如"0x"表示十六进制),在解析时,如果base设置为0,则会自动识别前缀;如果base设置为特定值(如8),则前缀会被忽略,除非字符串格式不正确。 区别: 1. 输入字符串的格式:八进制数通常以0开头(如"0777"),十六进制数以0x或0X开头(如"0xff"),十进制数没有前缀。 2. 解析时,如果指定了base(非0),则按照指定base解析;如果base为0,则根据前缀自动判断。 3. 输出时,我们可以选择任意进制进行格式化,但注意八进制十六进制的输出格式通常需要前缀,Go的格式化函数默认不添加前缀,但我们可以通过格式字符串添加(如`fmt`包中的格式化输出)。 另外,引用[4]中展示了使用`fmt`包直接格式化整数的方法,例如: %d 表示十进制 %o 表示八进制(不带前缀) %x 表示十六进制(小写,不带前缀) %#o 会添加八进制的前缀0 %#x 会添加十六进制的前缀0x 因此,我们有两种方式: 方式1:使用`strconv`包进行转换,然后使用`strconv.FormatInt`等函数格式化为字符串。 方式2:使用`fmt`包的格式化输出。 但用户要求的是将字符串数字转换为不同进制的字符串,所以我们需要先解析字符串为整数,然后再格式化为目标进制的字符串。 下面我们给出具体的代码示例,并解释每一步。</think>在Go语言中,将字符串形式的数字转换为不同进制需要理解底层存储机制和转换方法。数字在内存中始终以二进制存储,不同进制只是数据的不同表示形式[^2]。以下是具体实现方法和区别: ### 1. **字符串转十进制** ```go num, err := strconv.ParseInt("42", 10, 64) // 字符串"42" → 十进制int64 ``` - **基数**:第二个参数 `10` 表示源字符串是十进制格式 - **结果**:直接得到整数值,无需额外转换 ### 2. **字符串转八进制** ```go num, err := strconv.ParseInt("52", 8, 64) // 字符串"52" → 八进制值(实际存储为十进制42) fmt.Printf("%o", num) // 输出: 52 (八进制表示) ``` - **基数**:第二个参数 `8` 指定源字符串是八进制格式 - **前缀处理**:若字符串含 `0` 前缀(如 `"052"`),需手动去除: ```go s := strings.TrimPrefix("052", "0") num, _ = strconv.ParseInt(s, 8, 64) ``` ### 3. **字符串转十六进制** ```go num, err := strconv.ParseInt("2a", 16, 64) // 字符串"2a" → 十六进制值(十进制42) fmt.Printf("%x", num) // 输出: 2a (小写十六进制) ``` - **基数**:第二个参数 `16` 指定源字符串是十六进制格式 - **大小写**:`%X` 输出大写字母(如 `"2A"`) ### 4. **自动识别进制** ```go num, err := strconv.ParseInt("0x2a", 0, 64) // 自动识别0x前缀 ``` - **基数**:参数设为 `0` 时自动检测前缀: - `0x`/`0X` → 十六进制 - `0` → 八进制 - 无前缀 → 十进制 ### 5. **格式化输出** 使用 `fmt.Printf` 直接转换整数到不同进制: ```go num := 42 fmt.Printf("十进制:%d\n", num) // 42 fmt.Printf("八进制:%#o\n", num) // 052 (带0前缀) fmt.Printf("十六进制:%#x\n", num) // 0x2a (带0x前缀) ``` ### ⚠️ 核心区别 | **转换类型** | **基数参数** | **前缀处理** | **输出格式** | |--------------|--------------|--------------------|--------------------| | 十进制 | `10` | 无前缀 | 直接数值 | | 八进制 | `8` | 需手动处理 `0` | `%o` (无前缀) | | 十六进制 | `16` | 需手动处理 `0x` | `%x` (小写无前缀) | | 自动识别 | `0` | 自动识别前缀 | 根据原始格式 | > **关键点**:所有转换本质是 **字符串→整数(二进制存储)→目标进制字符串** 的过程。进制转换仅改变数据的表示形式,不改变内存中的二进制值[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值