所謂的大數相加就是,數字的長度超出了計算機int64的存儲范圍,需要使用字符串存儲進行相加
相加的邏輯,類似與我們小學算加法,列等式進行相加,如果大於等於10則需要進位
下面將用不同語言來實現
Python實現(支持帶小數點大數)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import random import time # 大數相加, 超出int64存儲范圍 def random_number(): """ 隨機生成一個大數 :return: """ length = random.randint(99, 9999) s = '' for i in range(length): s += str(random.randint(0, 9)) return s def strToList(s): """ 字符串轉換為列表 :param s: :return: """ l = [] for i in range(len(s)): l.append(s[i]) return l def floadBigAdd(a, b, c, d): """ 計算帶小數點的大數 :param a: :param b: :return: """ max_x = max(len(c), len(d)) # 獲取小數點后最長的長度 x = bigAdd(c, d) # 計算小數點后相加的結果 if len(x) > max_x: # 如果小數點計算后長度大於原先的長度,則進行進位1,小數點計算去除第一位 # 小數點前的數進行加1 a_l = strToList(a) a_l[0] = str(int(a_l[0]) + 1) a = ''.join(a_l) # 小數點后的數去除第一位 x_l = strToList(x) x_l.pop(0) x = ''.join(x_l) s = bigAdd(a, b) return s + '.' + x def bigAdd(a, b): """ 大數相加 :param a: :param b: :return: """ # 反轉字符串之后轉換為列表 a = strToList(a[::-1]) b = strToList(b[::-1]) c = [] # 定義存儲結果的列表 max_str = [0] # 定義不同位數存儲列表,默認有一個數,如果位數相同且最后移為計算進1為,取值時會報錯 # 獲取最短的數字長度 if len(a) > len(b): length = len(b) max_str = a[length:] # 取出最長字符串超出最短的部分 elif len(a) < len(b): length = len(a) max_str = b[length:] else: length = len(a) t = 0 # 定義進位值 for i in range(length): # 循環計算值 t1 = int(a[i]) + int(b[i]) if t1 >= 10: t1 = t1 - 10 c.append(str(t1 + int(t))) t = 1 # 大於10下一次計算進位1 else: c.append(str(t1 + int(t))) t = 0 # 小於10下一次計算進位0 if t == 1: # 如果最后一次進位為1,將在超出部分加1 max_str[0] = str(int(max_str[0]) + t) if max_str[-1] == 0: max_str = [] c.extend(max_str) # 計算合並列表 sum = ''.join(c) # 拼接字符串 return sum[::-1] # 反轉字符串即為最后的計算結果 def main(a, b): """ 算法開始 :param a: :param b: :return: """ start_time = time.time() if '.' in a or '.' in b: a1, a2 = a.split('.')[0], a.split('.')[1] if len(a.split('.')) > 1 else [] b1, b2 = b.split('.')[0], b.split('.')[1] if len(b.split('.')) > 1 else [] c = floadBigAdd(a1, b1, a2, b2) else: c = bigAdd(a, b) print("Use Time: ", time.time() - start_time) return c if __name__ == '__main__': ty = input("select Type(r/i): ") # 選擇是隨機生成大數,還是手動輸入數字 a, b = '', '' if ty == 'r': a, b = random_number(), random_number() elif ty == 'i': a = str(input('A= ')) b = str(input('B= ')) else: exit("Input Error") print("A(%s):" % (len(a)), a) print("B(%s):" % (len(b)), b) c = main(a, b) print(c)
GO語言實現
package main import ( "bufio" "fmt" "os" "strings" ) func bigAdd(str1, str2 string) (result string) { if len(str1) == 0 && len(str2) == 0 { return "0" } index1 := len(str1) - 1 index2 := len(str2) - 1 var left int for index1 >= 0 && index2 >= 0 { c1 := str1[index1] - '0' c2 := str2[index2] - '0' sum := int(c1) + int(c2) + left if sum >= 10 { left = 1 } else { left = 0 } c3 := (sum % 10) + '0' result = fmt.Sprintf("%c%s", c3, result) index1-- index2-- } for index1 >= 0 { c1 := str1[index1] - '0' sum := int(c1) + left if sum >= 10 { left = 1 } else { left = 0 } c3 := (sum % 10) + '0' result = fmt.Sprintf("%c%s", c3, result) index1-- } for index2 >= 0 { c2 := str2[index2] - '0' sum := int(c2) + left if sum >= 10 { left = 1 } else { left = 0 } c3 := (sum % 10) + '0' result = fmt.Sprintf("%c%s", c3, result) index2-- } if left == 1 { result = fmt.Sprintf("1%s", result) } return } func main() { r := bufio.NewReader(os.Stdin) s, _, error := r.ReadLine() if error != nil { fmt.Println("Input info has error:", error) return } strSlice := strings.Split(string(s), "+") if len(strSlice) <= 1 { fmt.Println("Input info has error") return } strNumber1 := strings.TrimSpace(strSlice[0]) strNumber2 := strings.TrimSpace(strSlice[1]) result := bigAdd(strNumber1, strNumber2) fmt.Println(result) }