//: [Previous](@previous) // Xcode で Editor メニュー > Show Render Markup でお読みください //import UIKit import Foundation /*: # 中学1年の数学 */ /*: ## 資料の整理と活用 */ /*: ### 近似値と有効数字 */ /*: #### 四捨五入、切り上げ、切り捨て */ print("四捨五入") for x in stride(from: 163.5, through: 164.5, by: 0.1) { var 四捨五入 = x 四捨五入.round(.toNearestOrAwayFromZero) print(x, 四捨五入) } print("切り上げ") for x in stride(from: 163.0, through: 164.0, by: 0.1) { var 切り上げ = x 切り上げ.round(.awayFromZero) print(x, 切り上げ) } print("切り捨て") for x in stride(from: 164.0, through: 165.0, by: 0.1) { var 切り捨て = x 切り捨て.round(.towardZero) print(x, 切り捨て) } /*: #### 正負の四捨五入、切り上げ、切り捨て */ print("正負の四捨五入") for i in -10...10 { var x = Double(i)/10.0, 四捨五入 = x 四捨五入.round(.toNearestOrAwayFromZero) print(String(format: "%g %g", x, 四捨五入)) } print("正負の切り上げ") for i in -10...10 { var x = Double(i)/10.0, 切り上げ = x 切り上げ.round(.awayFromZero) print(String(format: "%g %g", x, 切り上げ)) } print("正負の切り捨て") for i in -10...10 { var x = Double(i)/10.0, 切り捨て = x 切り捨て.round(.towardZero) print(String(format: "%g %g", x, 切り捨て)) } /*: ## 参考文献 1. [Wiki Pedia, 端数処理](https://ja.wikipedia.org/wiki/%E7%AB%AF%E6%95%B0%E5%87%A6%E7%90%86) 2. [Wiki Pedia, 剰余演算](https://ja.wikipedia.org/wiki/%E5%89%B0%E4%BD%99%E6%BC%94%E7%AE%97) */ /*: #### 桁数 */ print("桁数の算出") do { var x = 1.0 // 初項 1 から let f = 10.0 // 公比 10 で while x <= pow(10, 5) { // 100000 まで繰り返す let X = [ x, // これに、以下の公比 10^{1/5} も計算 x * pow(10.0, 0.2), x * pow(10.0, 0.4), x * pow(10.0, 0.6), x * pow(10.0, 0.8), ] for v in X { // 配列 X の要素 v すべてについて、桁数を表示 print(v, Int(log10(v).rounded(.towardZero)) + 1) // 桁数は ⌊log_{10}(v)⌋ + 1 で求まる。 //print(v, Int((log(v)/log(10)).rounded(.towardZero)) + 1) // log(v)/log(10) + 1、つまり ⌊ln(v)/ln(10)⌋ + 1 だと数値誤差で、例えば 1000 のときに正しく求まらないので注意 } x *= f // 公比を次々掛けて、繰り返し } } /*: #### 有効数字の表し方 */ print("有効数字: String(format:...) を用いる") print(String(format: "%10.4e", 149600000.0)) // "1.4960e+08\n", 10 は全体の文字数で、4 が小数部の桁数 print(String(format: "%7.1e", 0.0543)) // "5.4e-02\n", 7 は全体の文字数で、1 が小数部の桁数 print(String(format: "%8.2e", 0.009987)) // "1.00e-02\n", 8 が全体の文字数で、2 が小数部の桁数 // 以上を String(format:...) に頼らずに行う。 print("有効数字: log10(_) を用いる") do { let x = 149600000.0 let 整数部の桁数 = 1, 有効数字の桁数 = 5 log10(x) // 8.17 なので ⌊8.17⌋ + 1 で桁数となる let 桁数 = Int(log10(x).rounded(.towardZero)) + 1 // 9 let 小数部の桁数 = 桁数 - 整数部の桁数 // 8 let y = x/pow(10.0, Double(小数部の桁数)) // 1.496, x/(10^8) print("\(y)".padding(toLength: 有効数字の桁数 + 1, withPad: "0", startingAt: 0) + "×10^{\(小数部の桁数)}") // 1.4960×10^8, "\(y)" そのままだと最後の零が切り捨てられてしまうので、ピリオド 1 文字を加えた文字数まで "0" パディング } do { let 小数位 = 4 var x = 0.0543*pow(10.0, Double(小数位 - 1)) // 54.3、四捨五入したい小数位を小数第一位にスケール x = x.rounded(.toNearestOrAwayFromZero)*10 // 54*10、それを整数第一位にスケール let 整数部の桁数 = 1, 有効数字の桁数 = 2 log10(x) // 2.73 なので ⌊2.73⌋ + 1 で桁数となる let 桁数 = Int(log10(x).rounded(.towardZero)) + 1 // 3 let 小数部の桁数 = 桁数 - 整数部の桁数 // 2 let y = x/pow(10.0, Double(小数部の桁数)) // 5.4, x/(10^2) print("\(y)".padding(toLength: 有効数字の桁数 + 1, withPad: "0", startingAt: 0) + "×10^{\(小数部の桁数 - 小数位)}") // 5.4×10^{-2}, "\(y)" そのままだと最後の零が切り捨てられてしまう(かもしれない)ので、ピリオド 1 文字を加えた文字数まで "0" パディング、の役目だが、この場合は結果的に何もしていない } do { let 小数位 = 5 var x = 0.009987*pow(10.0, Double(小数位 - 1)) // 99.87、四捨五入したい小数位を小数第一位にスケール x = x.rounded(.toNearestOrAwayFromZero)*10 // 1000、それを整数第一位にスケール let 整数部の桁数 = 1, 有効数字の桁数 = 3 log10(x).rounded(.towardZero) // 3.0 なので ⌊3.0⌋ + 1 で桁数となる let 桁数 = Int(log10(x).rounded(.towardZero)) + 1 // 3 let 小数部の桁数 = 桁数 - 整数部の桁数 // 2 let y = x/pow(10.0, Double(小数部の桁数)) // 5.43, x/(10^8) print("\(y)".padding(toLength: 有効数字の桁数 + 1, withPad: "0", startingAt: 0) + "×10^{\(小数部の桁数 - 小数位)}") // 1.00×10^{-2}, "\(y)" そのままだと最後の零が切り捨てられてしまうので、ピリオド 1 文字を加えた文字数まで "0" パディング } //: この手続きを関数にして、再利用可能にする func 数の有効数字のString(数: Double, 有効数字の桁数: Int, 小数位: Int = 0, 整数部の桁数: Int = 1) -> String { var x = 数 if 0 < 小数位 { x = x*pow(10.0, Double(小数位 - 1)) // x*10^{小数位-1}、四捨五入したい小数位を小数第一位にスケール x = x.rounded(.toNearestOrAwayFromZero)*10 // {xの四捨五入}*10、それを整数第一位にスケール x = x/pow(10.0, Double(小数位)) // x/10^小数位、スケールを元に戻す } else if 小数位 < 0 { let 整数位 = -小数位 x = x/pow(10.0, Double(整数位)) // x/10^整数位、四捨五入したい整数位を小数第一位にスケール x = x.rounded(.toNearestOrAwayFromZero) // xの四捨五入 x = x*pow(10.0, Double(整数位)) // x*10^整数位、スケールを元に戻す } return String(format: "%*.*e", 有効数字の桁数 + 1, 有効数字の桁数 - 整数部の桁数, x) // 最後の最後で String(format:) を結局使ってしまっている、ので、もう少し以下で頑張ってみる } func 数の有効数字の文字列(数: Double, 有効数字の桁数: Int, 小数位: Int = 0, 整数部の桁数: Int = 1) -> String { var x = 数 if 0 < 小数位 { x = x*pow(10.0, Double(小数位 - 1)) // x*10^{小数位-1}、四捨五入したい小数位を小数第一位にスケール x = x.rounded(.toNearestOrAwayFromZero)*10 // {xの四捨五入}*10、それを整数第一位にスケール } else if 小数位 < 0 { let 整数位 = -小数位 x = x/pow(10.0, Double(整数位)) // x/10^整数位、四捨五入したい整数位を小数第一位にスケール x = x.rounded(.toNearestOrAwayFromZero) // xの四捨五入 } // ⌊x⌋ + 1 で桁数となる let 桁数 = Int(log10(x).rounded(.towardZero)) + 1 let 小数部の桁数 = 桁数 - 整数部の桁数 let y = x/pow(10.0, Double(小数部の桁数)) return "\(y)".padding(toLength: 有効数字の桁数 + 1, withPad: "0", startingAt: 0) + "×10^{\(小数部の桁数 - 小数位)}" } print("例題115: 数の有効数字のString(数:有効数字の桁数:小数位:整数部の桁数) を用いる") print(数の有効数字のString(数: 149600000.0, 有効数字の桁数: 5)) print(数の有効数字のString(数: 0.0543, 有効数字の桁数: 2, 小数位: 4)) print(数の有効数字のString(数: 0.009987, 有効数字の桁数: 3, 小数位: 5)) print("例題115: 数の有効数字の文字列(数:有効数字の桁数:小数位:整数部の桁数) を用いる") print(数の有効数字の文字列(数: 149600000.0, 有効数字の桁数: 5)) print(数の有効数字の文字列(数: 0.0543, 有効数字の桁数: 2, 小数位: 4)) print(数の有効数字の文字列(数: 0.009987, 有効数字の桁数: 3, 小数位: 5)) print("練習115: 数の有効数字のString(数:有効数字の桁数:小数位:整数部の桁数) による") print(数の有効数字のString(数: 50800.0, 有効数字の桁数: 3)) // 5.08e+04 print(数の有効数字のString(数: 0.0078, 有効数字の桁数: 2, 小数位: 5)) // 7.8e-03 print(数の有効数字のString(数: 830000.0, 有効数字の桁数: 4)) // 8.300e+05 // 応用 print(数の有効数字のString(数: 50800.5, 有効数字の桁数: 5)) // 5.0800e+04 print(数の有効数字のString(数: 50800.5, 有効数字の桁数: 5, 小数位: 1)) // 5.0801e+04 print(数の有効数字のString(数: 50800.5, 有効数字の桁数: 5, 小数位: -3)) // 5.1000e+04 print("練習115: 数の有効数字の文字列(数:有効数字の桁数:小数位:整数部の桁数) による") print(数の有効数字の文字列(数: 50800.0, 有効数字の桁数: 3)) // 5.08×10^{4} print(数の有効数字の文字列(数: 0.0078, 有効数字の桁数: 2, 小数位: 5)) // 7.8×10^{-3} print(数の有効数字の文字列(数: 830000.0, 有効数字の桁数: 4)) // 8.300×10^{5} // 応用 print(数の有効数字の文字列(数: 50800.5, 有効数字の桁数: 5)) // 5.0800×10^{4} print(数の有効数字の文字列(数: 50800.5, 有効数字の桁数: 5, 小数位: 1)) // 5.0801×10^{4} print(数の有効数字の文字列(数: 50800.5, 有効数字の桁数: 5, 小数位: -3)) // 5.1000×10^{4} //: [Next](@next)