- 和高精度加法差不多
- 新建整数t=0,用于保存借位
- 将各个位置上的数进行相减,得出每一位的结果和借位值
代码
package main
import (
"fmt"
)
// 判断是否有A>=B
func cmp(A, B []int) bool {
if len(A) != len(B) {
return len(A) > len(B)
}
for i := 0; i < len(A); i++ {
if A[i] != B[i] {
return A[i] > B[i]
}
}
return true
}
func Sub(A, B []int) {
C := make([]int, 0)
for i, t := 0, 0; i < len(A); i++ {
t = A[i] - t
if i < len(B) {
t -= B[i]
}
C = append(C, (t+10)%10)
if t >= 0 {
t = 0
} else {
t = 1
}
}
for len(C) > 1 && C[len(C)-1] == 0 {
C = C[:len(C)-1]
}
for i := len(C) - 1; i >= 0; i-- {
fmt.Print(C[i])
}
}
func main() {
var a, b string
fmt.Scanf("%s %s", &a, &b)
A, B := make([]int, len(a)), make([]int, len(b))
for i := len(a) - 1; i >= 0; i-- {
A[len(a)-1-i] = int(a[i] - 48)
}
for i := len(b) - 1; i >= 0; i-- {
B[len(b)-1-i] = int(b[i] - 48)
}
if cmp(A, B) {
Sub(A, B)
} else {
fmt.Print("-")
Sub(B, A)
}
}
需要注意的点
- 相减为负数的处理
- 需要对a,b的大小进行判断。若a>=b则为正整数,无需处理;若a<b则为负数,需要在输出时加前导"-"
-
前导0的处理
- 在得出逆序的结果数组C后,需要将后边多余的0去掉,但要注意结果为0的情况
代码技巧
相减后t的处理
- 当
t>=0
时,结果为t
;当t<0
时,结果为10-t
(因为借了10) - 改写为
t=(t+10)%10
。用一个式子便可表示。
两个高精度数的大小比较
- 比较两个数的位数,位数多的数一定大
- 两个数从前往后比较,若比较的当前位不同,则结果为两者的大小结果
拓展
A B可以为正数或负数该怎么处理?
绝对值相减相加,判断字符串首字符的类型。
-
正正
:直接计算 -
正负
:转化为高精度加法 -
负负
:高精度加法,加前导-