Github地址:https://github.com/kptanjunhao/calculator/blob/master/LongNumOperation.swift
import Foundation
//大数加法Long Number Plus Method
//为了避免影响原生字符串拼接,使用++作为加法符号。
//To avoid the original String connection,I use ++ as the plus operator.
infix operator ++{
associativity left precedence 140
}
func ++(left:String,right:String) -> String{
var resultstr = String()
var leftstr = [String]()
var rightstr = [String]()
//将数字分割成小数部分以及整数部分
//Separated the number into decimal part and integer part
if left.containsString(“.”){
leftstr = left.componentsSeparatedByString(“.”)
}else{
leftstr = [left]
}
if right.containsString(“.”){
rightstr = right.componentsSeparatedByString(“.”)
}else{
rightstr = [right]
}
//处理小数部分 Deal the decimal number.
//小数状态0代表左右都有小数部分,1代表左边有小数右边没,2代表右边有小数左边没,3代表两边都没有小数
/**
* 0:Either left number and right number both have the decimal part
* 1:Only left number has the decimal part
* 2:Only right number has the decimal part
* 3:Both sides do not have the decimal part.
*/
let decimalStatu = leftstr.count == 2 && rightstr.count == 2 ? 0 : (leftstr.count == 1 && rightstr.count == 1 ? 3 : leftstr.count == 2 && rightstr.count != 2 ? 1 : 2)
var decimalCanPlus1 = false//The value show the decimal part will full to integer part.一个显示小数位相加后是否可以使整数加1的状态值
switch decimalStatu {
case 0:
resultstr.appendContentsOf(“.”)
let leftIsLonger = leftstr[1] > rightstr[1]
var pstrlong = [Int]()
var pstrshort = [Int]()
for char in (leftIsLonger ? leftstr[1] : rightstr[1]).characters{
pstrlong.insert(Int(String(char))!, atIndex: 0)
}
for char in (!leftIsLonger ? leftstr[1] : rightstr[1]).characters{
pstrshort.insert(Int(String(char))!, atIndex: 0)
}
for index in pstrshort.count..<pstrlong.count{
resultstr.insert(Character(String(pstrlong[index])), atIndex: resultstr.startIndex.advancedBy(1))
}
for index in 0..<pstrshort.count{
//如果小数可以进位,则末位加1.只加一次
//If decimal part can full to integer part,integer last number plus 1,only plus once.
var curResult = pstrlong[index] + pstrshort[index] + (decimalCanPlus1 ? 1 : 0)
if curResult >= 10{
curResult -= 10
decimalCanPlus1 = true
}else{
decimalCanPlus1 = false
}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex.advancedBy(1))
}
case 1:
resultstr.appendContentsOf(“.”)
for curNum in leftstr[1].characters{
resultstr.append(curNum)
}
case 2:
resultstr.appendContentsOf(“.”)
for curNum in rightstr[1].characters{
resultstr.append(curNum)
}
case 3:
break
default:
fatalError(“decimalStatu can not detect two numbers statu”)
}
//处理整数部分 Deal with the integer part
var leftarray = [Int]()
for char in leftstr[0].characters{
leftarray.insert(Int(String(char))!, atIndex: 0)
}
var rightarray = [Int]()
for char in rightstr[0].characters{
rightarray.insert(Int(String(char))!, atIndex: 0)
}
//较短数的数位
//The shorter number’s count
let minCount = leftarray.count>rightarray.count ? rightarray.count : leftarray.count
//数字相加后是否会进十的状态值
//After plusing , if the result greater than 10,this value turns true.
var isGreaterThanTen = false
for index in 0..<minCount{
var curResult = leftarray[index] + rightarray[index] + (isGreaterThanTen ? 1 : 0) + (decimalCanPlus1 ? 1 : 0)
isGreaterThanTen = curResult >= 10
decimalCanPlus1 = false
if isGreaterThanTen{curResult -= 10}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex)
}
//指定较长的数,来完成短数位后的运算
//Continue calculate the value after finished the shortnumber dealing.
let longArray = leftarray.count>rightarray.count ? leftarray : rightarray
for index in minCount..<(longArray.count){
var curResult = longArray[index]
if isGreaterThanTen{
curResult += 1
isGreaterThanTen = curResult >= 10
if isGreaterThanTen{
curResult -= 10
}
}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex)
}
//如果计算完毕后,仍会进十,则在首位加1
//if finished all the calculates,the result still can carrybit,then add 1 to the first position.
if isGreaterThanTen{
resultstr.insert(“1”, atIndex: resultstr.startIndex)
}
return resultstr
}
func -(left:String,right:String) -> String{
var resultstr = String()
var leftstr = [String]()
var rightstr = [String]()
//将数字分割成小数部分以及整数部分
//Separated the number into decimal part and integer part
if left.containsString(“.”){
leftstr = left.componentsSeparatedByString(“.”)
}else{
leftstr = [left]
}
if right.containsString(“.”){
rightstr = right.componentsSeparatedByString(“.”)
}else{
rightstr = [right]
}
//储存整数部分数组
var leftArray = [Int]()
for char in leftstr[0].characters{
leftArray.insert(Int(String(char))!, atIndex: 0)
}
var rightArray = [Int]()
for char in rightstr[0].characters{
rightArray.insert(Int(String(char))!, atIndex: 0)
}
//储存小数部分数组
var leftDecArray = [Int]()
var rightDecArray = [Int]()
//声明较短小数的数位
var shortCount = 0
//小数状态0代表左右都有小数部分,1代表左边有小数右边没,2代表右边有小数左边没,3代表两边都没有小数
/**
* 0:Either left number and right number both have the decimal part
* 1:Only left number has the decimal part
* 2:Only right number has the decimal part
* 3:Both sides do not have the decimal part.
*/
let decimalStatu = leftstr.count == 2 && rightstr.count == 2 ? 0 : (leftstr.count == 1 && rightstr.count == 1 ? 3 : leftstr.count == 2 && rightstr.count != 2 ? 1 : 2)
switch decimalStatu {
case 0:
shortCount = leftstr[1].characters.count > rightstr[1].characters.count ? rightstr[1].characters.count : leftstr[1].characters.count
for char in leftstr[1].characters{
leftDecArray.append(Int(String(char))!)
}
for char in rightstr[1].characters{
rightDecArray.append(Int(String(char))!)
}
case 1:
for char in leftstr[1].characters{
leftDecArray.append(Int(String(char))!)
}
case 2:
for char in rightstr[1].characters{
rightDecArray.append(Int(String(char))!)
}
default:
break
}
//判断最后结果是正数还是负数
var resultIsPositive: Bool? = nil
//首先判断整数位数
if leftstr[0].characters.count > rightstr[0].characters.count{
resultIsPositive = true
}else if leftstr[0].characters.count == rightstr[0].characters.count{
//如果整数位数相同,则遍历判断
for index in 0..<leftArray.count{
if leftArray[index] == rightArray[index]{
continue
}
if leftArray[index] > rightArray[index]{
resultIsPositive = true
break
}
if leftArray[index] < rightArray[index]{
resultIsPositive = false
}
}
}else{
//如果整数位左边比右边小,则
resultIsPositive = false
}
//如果整数完全相等无法判断,则判断小数位
if resultIsPositive == nil{
switch decimalStatu {
case 0:
for index in 0..<shortCount{
if leftDecArray[index] == rightDecArray[index]{
continue
}
if leftDecArray[index] > rightDecArray[index]{
resultIsPositive = true
break
}
if leftDecArray[index] < rightDecArray[index]{
resultIsPositive = false
}
}
if resultIsPositive == nil{
//如果整数位完全相等,而且小数也完全相等,而且小数位数也相同,则两个数相同,直接返回0
if leftstr[1].characters.count == rightstr[1].characters.count{
return “0”
}
if shortCount == leftstr[1].characters.count{
resultIsPositive = false
}else{
resultIsPositive = true
}
}
case 1:
resultIsPositive = true
case 2:
resultIsPositive = false
case 3:
//如果整数位完全相等,而且没有小数,则两个数相同,直接返回0
return “0”
default:
break
}
}
func reduce(statu: Bool){
var frontNumWillSub1 = false
//先算小数,正数情况下,小数状态有三种情况,0:两边都有,1:只有左边有,2:只有右边有
if decimalStatu == 0{
resultstr.appendContentsOf(“.”)
//右边小数比较多
if shortCount == leftDecArray.count{
var i = 1
for _ in shortCount..<rightDecArray.count{
var curResult = 0 – rightDecArray[rightDecArray.count – i] – (frontNumWillSub1 ? 1 : 0)
if curResult < 0{
curResult += 10
frontNumWillSub1 = true
}else{
frontNumWillSub1 = false
}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex.advancedBy(1))
i += 1
}
}else{
//左边小数比较多
for index in shortCount..<leftDecArray.count{
resultstr.insert(Character(String(leftDecArray[index])), atIndex: resultstr.endIndex)
}
}
for index in 0..<shortCount{
var curResult = leftDecArray[shortCount – 1 – index] – rightDecArray[shortCount – 1 – index] – (frontNumWillSub1 ? 1 : 0)
if curResult < 0{
curResult += 10
frontNumWillSub1 = true
}else{
frontNumWillSub1 = false
}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex.advancedBy(1))
}
}else if decimalStatu == (statu ? 1 : 2){
resultstr.appendContentsOf(“.”)
for curNum in leftDecArray{
resultstr.appendContentsOf(“\(curNum)”)
}
}else if decimalStatu == (statu ? 2 : 1){
resultstr.appendContentsOf(“.”)
var i = 1
for _ in 0..<rightDecArray.count{
var curResult = 0 – rightDecArray[rightDecArray.count – i] – (frontNumWillSub1 ? 1 : 0)
if curResult < 0{
curResult += 10
frontNumWillSub1 = true
}else{
frontNumWillSub1 = false
}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex.advancedBy(1))
i += 1
}
frontNumWillSub1 = true
}
//再算整数
for index in 0..<rightArray.count{
var curResult = leftArray[index] – rightArray[index] – (frontNumWillSub1 ? 1 : 0)
if curResult < 0{
curResult += 10
frontNumWillSub1 = true
}else{
frontNumWillSub1 = false
}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex)
}
if leftArray.count != rightArray.count{
for index in rightArray.count..<leftArray.count{
var curResult = leftArray[index] – (frontNumWillSub1 ? 1 : 0)
if curResult < 0{
curResult += 10
frontNumWillSub1 = true
}else{
frontNumWillSub1 = false
}
resultstr.insert(Character(String(curResult)), atIndex: resultstr.startIndex)
}
}
var index = 0
for _ in 0..<resultstr.characters.count{
if resultstr.hasPrefix(“0”) && !resultstr.hasPrefix(“0.”){
resultstr.removeAtIndex(resultstr.startIndex.advancedBy(index))
index = 0
}else{
break
}
}
}
func exchange(inout first:[Int],inout second:[Int]){
let temp = first
first = second
second = temp
}
if resultIsPositive!{
//如果结果是正数的减法
reduce(resultIsPositive!)
}else{
//如果结果是负数的减法
print(leftDecArray)
exchange(&leftArray, second: &rightArray)
exchange(&leftDecArray, second: &rightDecArray)
print(leftDecArray)
reduce(resultIsPositive!)
resultstr.insert(“-“, atIndex: resultstr.startIndex)
}
return resultstr
}
func *(left:String, right:String) -> String{
var resultstr = String()
//获取小数位数
//get how many number of the decimal part.
var leftCount = 0
var rightCount = 0
if let leftIndex = left.characters.indexOf(“.”){
leftCount = leftIndex.distanceTo(left.endIndex) – 1
}
if let rightIndex = right.characters.indexOf(“.”){
rightCount = rightIndex.distanceTo(right.endIndex) – 1
}
let pCount = leftCount + rightCount
//移除小数点并添加到数组
//remove the point(.) and add the number to array
let leftStr = left.stringByReplacingOccurrencesOfString(“.”, withString: “”)
let rightStr = right.stringByReplacingOccurrencesOfString(“.”, withString: “”)
var longArray = [Int]()
var shortArray = [Int]()
let resultArray = NSMutableArray()
for char in (leftStr.characters.count >= right.characters.count ? leftStr.characters : rightStr.characters){
longArray.insert(Int(String(char))!, atIndex: 0)
}
for char in (leftStr.characters.count < right.characters.count ? leftStr.characters : rightStr.characters){
shortArray.insert(Int(String(char))!, atIndex: 0)
}
//进行逐位乘法运算
//multiply number one by one.Like 1,234 * 12 = 1,234 * 1 * 10 + 1,234 * 2
for shortIndex in 0..<shortArray.count{
var tempCarry = 0
var tempArray = [Int]()
var tempStr = “”
//每位运算都在最后一位添加0
//Add 0 to last position when calculating.Like 1,234 * 1 * 10 = 12,340 * 1
for _ in 0..<shortIndex{
tempArray.append(0)
tempStr.insert(Character(“0”), atIndex: tempStr.startIndex)
}
for longIndex in 0..<longArray.count{
var curResult = shortArray[shortIndex] * longArray[longIndex] + tempCarry
tempCarry = curResult/10
curResult = curResult%10
tempArray.append(curResult)
tempStr.insert(Character(“\(curResult)”), atIndex: tempStr.startIndex)
}
if tempCarry != 0{
tempArray.append(tempCarry)
tempStr.insert(Character(“\(tempCarry)”), atIndex: tempStr.startIndex)
}
resultArray.addObject(tempStr)
}
//将乘法之后的结果相加起来
//Add all the multiply result
resultstr = resultArray[0] as! String
for index in 1..<resultArray.count{
resultstr = resultstr ++ (resultArray[index] as! String)
}
if pCount != 0{
resultstr.insert(“.”, atIndex: resultstr.endIndex.advancedBy(-pCount))
}
return resultstr
}