• 经典问题--超大字符串型整数加减


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


    fmt.Println(9223372036854775808)

    执行结果:
    constant 9223372036854775808 overflows int
    • 1

    但当有相关需求,如假设π小数点后50位乘以 的值为a1, e小数点后30位乘以 的值为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
      num[x-i] = int(n1[x-1-i]-'0') + int(n2[y-1-i]-'0')
      i = i + 1
     }

     for i:=0;i
      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
    }


    • 1

    运行结果:

    314159265358979323848982620156409333655077227408862
    • 1

    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
       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
    }



    • 1

    运行结果:

     314159265358979323843546056499491243184356652466158

    • 1

    思考:当str1,str2未必为整数型字符串,而可能是小数型时,该如何处理?
    以及超大字符串型整数的乘除问题,如何处理

    本文由 mdnice 多平台发布

  • 相关阅读:
    推荐几种可以直接翻译PDF英文文献的方法
    【计组】为什么计算机采用补码进行运算?
    学生网站模板—千岛湖旅游(6页) HTML+CSS+JavaScript web网页设计—— 出游 旅途
    数据结构与算法之美 复杂度分析(上)
    DockerFile常用保留字指令及知识点合集
    # 【Android】逆向自动化
    POJO>JavaBean
    Win7 easy connect 提示:选路连接失败,可能当前连接网络异常,请稍后重试
    verilog实现分频(奇数分频和偶数分频,通用版)
    二〇二二年终总结
  • 原文地址:https://blog.csdn.net/techdashen/article/details/133801200