我搞不懂浮點數:CS 101 - yllan === {%hackmd FGRWt1UuTFKk0wSbGgg-SA %} ## YouTube {%youtube l6fDexqFzqQ %} ## Slide {%speakerdeck yllan/wo-gao-bu-dong-fu-dian-shu %} ## 預備知識 - 指數運算 ``` 2^3 = 2 * 2 * 2 = 8 2^0 = 1 2^(-3) = 1 / 8 ``` ## 議程目標 希望新手聽完,能知道浮點數運作原理。 老手能夠學到一些edge case。 大家都能避開常見的坑。 ## 0.1+0.2 * https://0.30000000000000004.com/ 定點數 浮點數 ![](https://i.imgur.com/2Id3ZoQ.jpg) ![](https://i.imgur.com/rEc7LKa.jpg) 19.9 ~ 10011.1110011001100.... ![](https://i.imgur.com/MCjnlhz.jpg) ![](https://i.imgur.com/CGAYP83.jpg) ![](https://i.imgur.com/j2KlHnU.jpg) ![](https://i.imgur.com/L2iX8GV.jpg) ```swift func testFloatEqual() { let e:Double = 1.9 * 10 * 10 let r:Double = 1.9 * 100 XCTAssertEqual(e, r) // V XCTAssertNotEqual(e.description, r.description) // X } 求講者怎麼測的? ``` 浮點數的加法容易出現問題,盡量用乘的。誤差會比較小 與錢有關的,最好都不要扯上關係 **DON'T: Use floating point type to store money** ``` swift var m: Float = 0 for _ in 0..<1000000 { m += 0.01 } // m = 9865.22363 ``` **DO: Use Decimal type to store money** ``` swift var money: Decimal = 0 for _ in 0..<1000000 { money += Decimal(1) / Deciaml(100) } // money = 10000.000000 ``` ![](https://i.imgur.com/vRc3wPY.jpg) ![](https://i.imgur.com/KcQOaVE.jpg) ![](https://i.imgur.com/1hG4Kse.jpg) 能用 `Double` 就不要用 `Float` 浮點數運算要避免大數字與小數字加減 range取 max(0.01, utl) ###### tags:`iPlayground2019`