大数加法、大数乘法、大数减法。Swift。
来源:互联网 发布:软件如何做授权加密 编辑:程序博客网 时间:2024/03/29 05:22
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 precedence140
}
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 charin (leftIsLonger ? leftstr[1] : rightstr[1]).characters{
pstrlong.insert(Int(String(char))!, atIndex:0)
}
for charin (!leftIsLonger ? leftstr[1] : rightstr[1]).characters{
pstrshort.insert(Int(String(char))!, atIndex:0)
}
for indexin pstrshort.count..<pstrlong.count{
resultstr.insert(Character(String(pstrlong[index])), atIndex: resultstr.startIndex.advancedBy(1))
}
for indexin 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 curNumin leftstr[1].characters{
resultstr.append(curNum)
}
case 2:
resultstr.appendContentsOf(".")
for curNumin 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 charin leftstr[0].characters{
leftarray.insert(Int(String(char))!, atIndex:0)
}
var rightarray = [Int]()
for charin 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 indexin 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 indexin 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 charin leftstr[0].characters{
leftArray.insert(Int(String(char))!, atIndex:0)
}
var rightArray = [Int]()
for charin 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 charin leftstr[1].characters{
leftDecArray.append(Int(String(char))!)
}
for charin rightstr[1].characters{
rightDecArray.append(Int(String(char))!)
}
case 1:
for charin leftstr[1].characters{
leftDecArray.append(Int(String(char))!)
}
case 2:
for charin 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
}elseif leftstr[0].characters.count == rightstr[0].characters.count{
//如果整数位数相同,则遍历判断
for indexin 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 {
case0:
for indexin 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
}
}
case1:
resultIsPositive = true
case2:
resultIsPositive = false
case3:
//如果整数位完全相等,而且没有小数,则两个数相同,直接返回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 indexin shortCount..<leftDecArray.count{
resultstr.insert(Character(String(leftDecArray[index])), atIndex: resultstr.endIndex)
}
}
for indexin 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))
}
}elseif decimalStatu == (statu ?1 : 2){
resultstr.appendContentsOf(".")
for curNumin leftDecArray{
resultstr.appendContentsOf("\(curNum)")
}
}elseif decimalStatu == (statu ?2 : 1){
resultstr.appendContentsOf(".")
var i =1
for_ in0..<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 indexin 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 indexin 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_ in0..<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 charin (leftStr.characters.count >= right.characters.count ? leftStr.characters : rightStr.characters){
longArray.insert(Int(String(char))!, atIndex:0)
}
for charin (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 shortIndexin 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_ in0..<shortIndex{
tempArray.append(0)
tempStr.insert(Character("0"), atIndex: tempStr.startIndex)
}
for longIndexin 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 indexin 1..<resultArray.count{
resultstr = resultstr ++ (resultArray[index]as! String)
}
if pCount !=0{
resultstr.insert(".", atIndex: resultstr.endIndex.advancedBy(-pCount))
}
return resultstr
}
- 大数加法、大数乘法、大数减法。Swift。
- 大数减法、加法、乘法
- 大数加法、减法、乘法
- 大数乘法,大数加法,大数减法
- 大数加法.减法.乘法.除法
- 大数加法,减法,乘法总结
- 大数的加法,减法,乘法
- 大数加法、减法和乘法
- 使用C++类实现大数加法,大数减法,大数乘法
- 大数模板 大数加法,大数减法,大数乘法,大数除法,大数比较等操作
- 大数加法 大数乘法
- 大数加法和大数减法
- 大数运算——加法,减法,乘法
- 大数运算——加法,减法,乘法
- 大数运算——加法,减法,乘法 .
- 大数加法 减法 乘法 除法 高精度四则运算
- 大数加法 减法 乘法 除法 高精度四则运算
- 大数加法、减法、乘法、除法实现
- 用Git进行协同开发
- go语言的os.exec包介绍
- 蓝牙讲解上--搜索、配对
- 多位数与一位数相乘
- IOS使用Jenkins进行持续集成
- 大数加法、大数乘法、大数减法。Swift。
- 多对多表的连接关系
- codeforces 659 D. Bicycle Race
- 分库分表
- Android中线程同步
- V4L2视频采集驱动框架
- s5pv210 jpeg硬件编码
- 01-复杂度1 最大子列和问题
- shiro 第二节 身份验证