查看單個文章
  #9  
舊 2018-04-21, 06:46 PM
哈啦 的頭像
哈啦 哈啦 目前離線
論壇管理員
 
註冊日期: 2002-05-28
文章: 23,053
預設

引用:
作者: 哈啦 查看文章
就是對浮點數減法的部份會有問題,並未去解決。
在寫計算機程式時,有一個困擾就是浮點數的減法會出現誤差。例如:
123.005 - 123.004 會得到 0.0009999...... 而非預期中的 0.001 。
因此寫了一個函式來解決這問題。
基本上是先求出二個數小數點後的位數,以最多的為準,乘上十的次方,再乘回二數將它們都變成整數,相減之後,得到的結果再除以剛才的十的次方,再變回字串出來。
代碼:
//檢查小數點之後是否有數字
func pointCheck(s:String) -> Bool {
  let n = Double(s)
    if Double(Int(n!)) != n {
        return true
    } else {
        return false
         }
}


代碼:
//將二個含有小數點的數字相減
func subtractFloat(s1:String, s2:String) -> String { //輸入二個數字字串
    var c:Double = 0 //用做計算結果之用
    var k:Double = 1 //作為十的次方之用
    let n1:Double! = Double(s1) //轉換字串為浮點數
    let n2:Double! = Double(s2) //轉換字串為浮點數
    var a1 = Array(s1) //轉換字串為字元陣列
    var a2 = Array(s2) //轉換字串為字元陣列
    var counter1 = 0 //第一個陣列的元素個數
    var counter2 = 0 //第二個陣列的元素個數
    var afterPoint = 0 //看誰的小數點後面的數字個數多就給它
	
	//求出二個數字小數點之後的數字個數
    for i in 0...(a1.count-1) {
        if a1[i] == "." {
            counter1 = a1.count - i - 1
        }
    }
    for i in 0...(a2.count-1) {
        if a2[i] == "." {
            counter2 = a2.count - i - 1
        }
    }
	
	//將比較多的個數給予afterPoint
    if counter1 >= counter2 {
        afterPoint = counter1 }
    else {
        afterPoint = counter2
    }
    
	//將afterPoint當成十的次方數
    for _ in 1...afterPoint {
        k = k*10
    }
    
	
    c = (n1*k - n2*k)/k //先將二個數字乘上k都變成整數再相減,減完後再除以k回歸為浮點數
    
	
    return String(c) //將結果轉換成字串回傳

}

最終解決函式:
代碼:
func minus(str1:String,str2:String){
    if pointCheck(s:str1)||pointCheck(s:str2) {
    print(subtractFloat(s1:str1,s2:str2))
} else {
    print( String(Int(Double(str1)!) - Int(Double(str2)!)) ) /*為何在此還要先把已知無小點的字串先換成Double再Int呢?因為如果字串是 "33.0"這種的,直接Int("33.0")會得到 nil 的答案,而造成程式fatal error。所以再多加一層轉換來把關*/
}
}
__________________
咖啡走路
微博


您是網站站長嗎?歡迎到站長俱樂部 一起討論吧。
按我看版規
code.club
回覆時引用此篇文章