Swift Digest
SE-0552 | Swift Evolution↗

Float.pi の丸め

Rounding of Float.pi

Proposal
SE-0552↗
Authors
Stephen Canon
Review Manager
Doug Gregor
Status
Accepted

このダイジェストはClaude Opus 4.7 / 4.8によって生成されたものです(License)。原文はこちら↗。

01 何が問題だったのか

FloatingPoint プロトコルの pi プロパティは、円周率 π に最も近い表現可能な値を返しそうに見えますが、実際にはそうではありませんでした。

SE-0067 で FloatingPoint を設計した当時、π をどう丸めるべきかについて IEEE 754 は指針を示していませんでした。表現可能な値のうち π に最も近いものを返すか、π より確実に小さい側で最も近いもの(0 方向への丸め)を返すか、2 つの選択肢があり、Swift は後者を選びました。角度計算で結果が意図しない象限に入り込むのを避ける、という意図からです。

その結果、Float.pi は真の π よりわずかに小さい 0x1.921fb4p1 を返しており、π に最も近い表現可能な値にはなっていませんでした。これは他の言語での π の値とも一致せず、精度の面でも最良ではありませんでした。

その後、IEEE 754 のワーキンググループでは「何らかの不変条件を保つために精度の劣る値へ丸めるのではなく、実装が返せる最良の近似値を返すべきだ」という合意が形成されました。これを受けて、FloatingPoint.pi の定義もこの指針に合わせて見直すことになりました。

02 どのように解決されるのか

FloatingPoint.pi の定義を変更し、0 方向へ丸めることを要求しないようにします。あわせて Float.pi の値を、π より小さい側の 0x1.921fb4p1 から、π のすぐ上の表現可能な値である 0x1.921fb6p1 に更新します。これは π に最も近い表現可能な値です。

ドキュメントからは、次の「ユーザーの角度計算が誤った象限に入り込まないよう 0 方向へ丸める」という趣旨の一文が削除されます。

/// This value is rounded toward zero to keep user computations with angles
/// from inadvertently ending up in the wrong quadrant.

これにより、Float.pi は他の言語と同じく π に最も近い値を返すようになり、他言語で書かれたプログラムと同じ結果を得やすくなります。

既存の値に依存している場合

ごく一部のコードが、これまでの Float.pi(0x1.921fb4p1)という具体的な値に依存している可能性があります。そうした場合には、Float.pi の代わりに 0x1.921fb4p1 を直接書けば、従来の値を使い続けられます。このようなケースは多くないと見込まれており、他言語との結果の一致しやすさが一時的な手間を上回ると判断されています。