[Swift 3.0] 標準ライブラリに小数の四捨五入/切り捨て/切り上げが追加された話

2016.12.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

以前(〜2.x)までのSwiftには他の言語によくあるfloor()やceil()関数に相当するものがありませんでした。
Swift3.0からこれらの四捨五入や切り捨て、切り上げの関数が追加されました。

Swift Evolutionでいうところの下記の内容です。
SE-0113 Add integral rounding functions to FloatingPoint

どういった追加?

タイトル通りですが、浮動小数点数型(FloatやDouble)に四捨五入/切り捨て/切り上げの関数round()が追加されました。
round()の引数にはFloatingPointRoundingRuleという列挙型(enum)の値を設定します。(省略可能)
詳細を見てみましょう。

.round()

引数無しの場合、値を四捨五入します。

var value = 23.456
value.round()
print(value)      // 23.0
var value = 23.512
value.round()
print(value)     // 24.0

備考

.toNearestOrAwayFromZeroを指定した時と同じ挙動になり、“schoolbook rounding.”というルールが適用されます。

.rounded(.up)

.upを指定すると、数を切り上げます。
(C言語などのceil()と同じ挙動です。)

var value = 23.012
value.round(.up)     // 24.0
print(value)
var value = -23.012
value.round(.up)     // -23.0
print(value)

.rounded(.down)

.downを指定すると、数を切り捨てます。
(C言語などのfloor()と同じ挙動です。)

var value = 23.999
value.round(.down)     // 23.0
print(value)
var value = -23.999
value.round(.down)     // -24.0
print(value)

.rounded(.toNearestOrEven)

最近接偶数への丸め (round to the nearest even; RN)が適用されます。このルールは"bankers rounding"と呼ばれます。

最近接偶数への丸めとは?

最近接偶数への丸め (round to the nearest even; RN) は、端数が0.5より小さいなら切り捨て、端数が0.5より大きいならは切り上げ、端数がちょうど0.5なら切り捨てと切り上げのうち結果が偶数となる方へ丸める。JIS Z 8401で規則Aとして定められていて、規則B(四捨五入)より「望ましい」とされている。 [引用] 最近接偶数への丸め | Wikipedia

.rounded(.awayFromZero)

.awayFromZeroを指定すると、0から遠い数値になります。正の数は切り上げ、負の数は切り捨ての挙動です。

var value = 23.012
value.round(.awayFromZero)     // 24.0
print(value)
var value = -23.012
value.round(.awayFromZero)     // -24.0
print(value)

.rounded(.towardZero)

.towardZeroを指定すると、0に近い数値になります。正の数は切り捨て、負の数は切り上げの挙動です。

var value = 23.999
value.round(.towardZero)     // 23.0
print(value)
var value = -23.999
value.round(.towardZero)     // -23.0
print(value)

さいごに

今回のブログを書くにあたって、Wikipediaの端数処理のページを読んだのですが、色々な処理があるのを知って勉強になりました。
想定外の値(挙動)にならないように、それぞれの引数の挙動を理解したうえで利用しようと思います。