はじめ
浮動小数点数の配列の要素をすべて2乗して足し合わせるとき通常は
let array: [Double] = [0.0, 1.2, 1.3, 1.5, 1.6, 1.9, 2.4, 4.7]
let s0 = array.reduce(0.0) { r, e in r + e * e }
としますね。
ですが、Swiftには浮動小数点数に二つの浮動小数点数を掛けたものを加える、というちょっと変わった関数が備わっています。
これを使うと次のようになります。
let array: [Double] = [0.0, 1.2, 1.3, 1.5, 1.6, 1.9, 2.4, 4.7]
let s1 = array.reduce(0.0) { r, e in r.addingProduct(e, e) }
Appleのドキュメント addingProduct(::)
mutableなaddProductもあります。
Appleのドキュメント addProduct(::)
なにがうれしいのか
精度がいい
先の二つの計算結果を見てみると以下のようになっています
s0 = 39.400000000000006
s1 = 39.4
普通に2乗して足し合したものには浮動小数点数でおなじみのゴミがついていますが、addingProduct
を使った場合はそれがありません。
速い?
実はこのaddingproduct
はfma(fused multiply-add)という演算で最近のCPUにはほとんど実装されている演算です。
なのでたいていの場合は速いです。
精度が高いのもこのおかげですね。
おわり
この二つの数を掛け合わせたものを足すというfma
はやみくもに作られたものではなく、いろいろな分野で現れる計算なので知っておくといいかもしれません。