[还债] 高精度加法和高精度乘法

RoLingG 算法 2025-12-27

高精度加法和高精度乘法

高精度加法:

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

// 高精度加法:a + b,返回字符串(非负整数)
func bigAdd(a, b string) string {
    // 去掉前导 0
    a = strings.TrimLeft(a, "0")
    b = strings.TrimLeft(b, "0")
    if a == "" {
        a = "0"
    }
    if b == "" {
        b = "0"
    }

    // 倒序
    aa := make([]int, len(a))
    bb := make([]int, len(b))
    for i := 0; i < len(a); i++ {
        aa[i] = int(a[len(a)-1-i] - '0')
    }
    for i := 0; i < len(b); i++ {
        bb[i] = int(b[len(b)-1-i] - '0')
    }

    maxLen := max(len(aa), len(bb))
    res := make([]int, maxLen+1)

    // 逐位相加
    carry := 0
    for i := 0; i < maxLen || carry > 0; i++ {
        da := 0
        if i < len(aa) {
            da = aa[i]
        }
        db := 0
        if i < len(bb) {
            db = bb[i]
        }
        sum := da + db + carry
        res[i] = sum % 10
        carry = sum / 10
    }

    // 去高位 0
    k := len(res) - 1
    for k > 0 && res[k] == 0 {
        k--
    }
    res = res[:k+1]

    // 倒序拼字符串
    ans := make([]byte, len(res))
    for i := 0; i < len(res); i++ {
        ans[len(res)-1-i] = byte(res[i] + '0')
    }
    return string(ans)
}

func main() {
    in := bufio.NewReader(os.Stdin)
    var a, b string
    fmt.Fscan(in, &a, &b)
    fmt.Println(bigAdd(a, b))
}

高精度乘法:

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

// 高精度乘法:a*b,返回字符串形式的结果
func bigMul(a, b string) string {
    a = strings.TrimLeft(a, "0 ")
    b = strings.TrimLeft(b, "0 ")
    if a == "0" || a == "" || b == "0" || b == "" {
        return "0"
    }

    // 倒序转成 byte 数组,方便从低位开始算
    aa := []byte(a)
    bb := []byte(b)

    // 反转aa和bb,便于模拟人手算乘法
    for i := 0; i < len(aa)/2; i++ {
        aa[i], aa[len(aa)-1-i] = aa[len(aa)-1-i], aa[i]
    }
    for i := 0; i < len(bb)/2; i++ {
        bb[i], bb[len(bb)-1-i] = bb[len(bb)-1-i], bb[i]
    }

    // 结果最长 len(a)+len(b) 位
    res := make([]int, len(aa)+len(bb))

    // 竖式乘法
    for i := 0; i < len(aa); i++ {
        da := int(aa[i] - '0') // 将string转换成int
        carry := 0
        for j := 0; j < len(bb); j++ {
            db := int(bb[j] - '0')
            temp := da*db + res[i+j] + carry
            res[i+j] = temp % 10
            carry = temp / 10
        }
        res[i+len(bb)] += carry // 残余进位保留
    }
    fmt.Println(res)

    // 去除最高位剩余0
    for len(res) > 0 && res[len(res)-1] == 0 {
        res = res[:len(res)-1]
    }
    fmt.Println(res)

    // 倒序拼成字符串
    ans := make([]byte, len(res))
    for i := 0; i < len(res); i++ {
        ans[len(res)-1-i] = byte(res[i] + '0')
    }
    return string(ans)
}

func main() {
    in := bufio.NewReader(os.Stdin)
    var a, b string
    fmt.Fscan(in, &a, &b)
    fmt.Println(bigMul(a, b))
}

综合思路就是模拟人手算,先将两个数倒序,方便后续模拟手算运算,之后根据加法和乘法的相关竖式计算规则进行模拟编写处理逻辑就可以了。

PREV
[Git] 普通仓库和bare仓库
NEXT
[MongoDB] MongoDB-CVE-2025-14847漏洞

评论(0)

发布评论