[面试] 双字符串大数相乘

RoLingG 其他 2025-11-06

来自腾娱互动面试的题目,下面是代码结果:

// multiplyStrings 实现两个字符串数字的相乘
func multiplyStrings(num1, num2 string) string {
    // 使用 big.Int 来处理大数字
    a := new(big.Int)
    b := new(big.Int)
    a.SetString(num1, 10) // 将字符串 num1 转换为 big.Int,基数为 10
    b.SetString(num2, 10) // 将字符串 num2 转换为 big.Int,基数为 10

    // 相乘
    result := new(big.Int).Mul(a, b)

    // 将结果转换为字符串
    return result.String()
}

func main() {
    num1 := "9223372036854775809"
    num2 := "9223372036854775809"
    result := multiplyStrings(num1, num2)
    fmt.Println("结果是:", result)
}

// 运行结果:
// 结果是: 85070591730234615884290395931651604481

我一开始写的是下面这种↓

func multiplyStrings(num1, num2 string) string {
    _num1, _ := strconv.Atoi(num1)
    _num2, _ := strconv.Atoi(num2)
    fmt.Println(_num1, _num2)
    sum := _num1 * _num2
    _sum := strconv.Itoa(sum)
    return _sum
}

func main() {
    res := multiplyStrings("9223372036854775809", "9223372036854775809")
    fmt.Println(res)
}

// 运行结果:
// strconv.Atoi: parsing "9223372036854775809": value out of range
// strconv.Atoi: parsing "9223372036854775809": value out of range
// 9223372036854775807 9223372036854775807
// 1

从结果打印就可以看出输入与输出明显不对等,运行中出问题了,原因如下:

  • strconv.Atoi 用于将字符串转换为 int 类型。int 类型在 Go 中是一个有符号整数,其大小取决于平台(通常是 32 位或 64 位)。
  • 对于 32 位系统,int 的范围是 [−231,231−1],即 [−2147483648,2147483647]。
  • 对于 64 位系统,int 的范围是 [−263,263−1],即 [−9223372036854775808,9223372036854775807]。
  • 如果字符串表示的数字超出了 int 的范围,strconv.Atoi 会报错,但如果不进行错误处理,仍会继续执行,结果仍有问题。

big.Int 是用来处理任意精度整数的,它能够动态地分配内存以适应数字的大小

  • 动态内存分配big.Int 内部使用一个切片来存储数字的每一位。当数字变大时,它会自动扩展数组的大小。
  • 无固定大小限制:由于 big.Int 不依赖于固定的内存大小,它可以表示任意大的数字,只要系统的内存足够。
  • 高效算法big.Int 实现了高效的算法来处理大数字的加法、减法、乘法、除法等运算。这些算法通常比普通的整数运算更复杂,但可以处理任意大小的数字。

所以相比原来普通的 int 类型限制了内存上限大小,big.Int 动态分配内存的原因,能够使得它处理更多大的数。

PREV
[Go] 1.18版本后的Slice扩容
NEXT
[MySQL] MySQL遇到内存都装不下的数据表,如果要进行去重,该如何操作?

评论(0)

发布评论