超大字符串型整数加减

简介: 超大字符串型整数加减

int64所能表示的数字范围为-2^{63} 到 2^{63}-12632631,即-9223372036854775808~9223372036854775807, (19位长度),当超过这一数字,则会溢出

fmt.Println(9223372036854775808)
执行结果:
constant 9223372036854775808 overflows int

但当有相关需求,如假设π小数点后50位乘以105010^{50}1050的值为a1, e小数点后30位乘以103010^{30}1030的值为a2,现需要计算a1+a2,以及a1-a2的值;

即对两个可正可负的字符串型整数str1和str2,计算str1+str2的值

1.当两数皆为正整数

如a1+a2

一些必要操作,如去除最左边的所有0,在代码中不做展现,

默认已通过strings.TrimLeft(str,"0")处理为不是以0开头的正整数

func main(){
  str1 := "314159265358979323846264338327950288419716939937510"
  str2 :=                     "2718281828459045235360287471352"
  rs := ""
  if len(str1) > len(str2) {
    rs = AddStr(str1,str2)
  }  else{
    rs = AddStr(str2,str1)
  }
  fmt.Println(rs)
}
func AddStr(n1,n2 string)(res string) {
  var num []int
  x,y := len(n1),len(n2)
  num = make([]int,x+1) //因为可能存在两个数的最高位相加大于10的情况,故而比两者中最大数的位数+1
  for i :=0;i<y; {
    num[x-i] = int(n1[x-1-i]-'0') + int(n2[y-1-i]-'0')
    i = i + 1
  }
  for i:=0;i<x-y;{
    num[x-y-i] = int(n1[x-y-i-1]-'0')
    i = i + 1
  }
  //处理进位
  for i := len(num);i>1;{
    if num[i-1]/10==1 {
      num[i-1]-=10
      num[i-2]++
    }
    i = i - 1
  }
  //汇总字符串结果
  for _,i := range num{
    s:=strconv.Itoa(i)
    res+=s
  }
  //去除开头可能存在的0
  if len(res) > 1 {
    res = strings.TrimLeft(res,"0")
  }
  return
}

运行结果:

314159265358979323848982620156409333655077227408862

2.当两数可能为负整数

即a1-a2,或a2-a1,或-a1-a2

当两数皆为负数,先把负号取出,这样就和两个正整数相加无异,

最后得出结果再加上负号;

当两数一正一负,

如下代码,默认已做如下处理,a1为正,a2为负,且a1的绝对值>a2的绝对值

func main(){
  str1 := "314159265358979323846264338327950288419716939937510"
  str2 :=                    "-2718281828459045235360287471352"
  str2 = strings.TrimLeft(str2,"-")
  res := subtractStr(str1,str2)
  fmt.Println(res)
}
func subtractStr(n1,n2 string)(res string) {
  var num []int
  x,y := len(n1),len(n2)
  num= make([]int,x+1)
  for i := 0;i < y; {
    num[x-i] = int(n1[x-1-i]-'0') - int(n2[y-1-i]-'0')
    i = i + 1
  }
  for i:=0;i<x-y;{
    num[x-y-i] = int(n1[x-y-i-1]-'0')
    i = i + 1
  }
  //处理进位
  for i := len(num);i>1;{
    if num[i-1] < 0  {
      num[i-1]+=10
      num[i-2]--
    }
    i = i- 1
  }
  //汇总字符串结果
  for _,i := range num{
    s:=strconv.Itoa(i)
    res+=s
  }
  //去除开头可能存在的0
  if len(res) > 1 {
    res = strings.TrimLeft(res,"0")
  }
  return
}

运行结果:

 314159265358979323843546056499491243184356652466158

思考1:当str1,str2未必为整数型字符串,而可能是小数型时,该如何处理?

思考2:超大字符串型整数的乘除问题,如何处理

目录
相关文章
|
12月前
|
存储 IDE 编译器
整型在内存中的存储及运算规则
整型在内存中的存储及运算规则
|
4月前
|
存储
整数和浮点数在内存中存储
整数的2进制表⽰⽅法有三种,即原码、反码和补码。
31 0
|
4月前
|
存储 C语言
C中负数的存储形式 | 位运算符
C中负数的存储形式 | 位运算符
30 0
|
9月前
|
存储 C语言 C++
整数和浮点数在内存中的存储
整数和浮点数在内存中的存储
77 1
|
4月前
|
存储 小程序 编译器
整数和浮点数在内存中的存储​(大小端详解)
整数和浮点数在内存中的存储​(大小端详解)
|
4月前
|
存储 编译器 C语言
数据在内存中的存储(浮点数与整数的类型转换)
在c语言操作符那一篇文章中我们讲到整数的二进制表示方法有三种,即原码、反码和补码。 它们都由符号位和数值位组成,数值位中的最高位就是符号位,符号位中0表示”正“,1表示”负“,
|
9月前
|
存储
关于整数和浮点数在内存中的存储的总结
关于整数和浮点数在内存中的存储的总结
59 0
|
算法
超大字符串型整数乘除
超大字符串型整数乘除
55 0
|
存储 关系型数据库 MySQL
尽量使用数值替代字符串类型
尽量使用数值替代字符串类型
|
存储 机器学习/深度学习
求一个整数存储在内存中的二进制中1的个数;例如15有4个1(三种方法详解)
求一个整数存储在内存中的二进制中1的个数;例如15有4个1(三种方法详解)
130 0
求一个整数存储在内存中的二进制中1的个数;例如15有4个1(三种方法详解)