読者です 読者をやめる 読者になる 読者になる

その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

浮動小数点数の同一性チェックがだるいのでTest::LimitDecimalPlaces を書いた

perl

言いたいことはほとんどこのスライドに書いてます


言語を問わない話題ですが、浮動小数点数の同一性チェックがだるいです。
テストなんかで、処理によって得られた浮動小数点数が期待値と同一かどうかをチェックしたい場合、
愚直に書くとテストがコケる環境が出てきます。
拙作のモジュールでもその問題にぶち当たってテストをコケさせてました。

その辺りの詳しい事はid:syohex さんから頂いたISSUE が詳しいです。
Failed test 04.test_poc_without_fft.t · Issue #1 · moznion/Math--PhaseOnlyCorrelation · GitHub
本当にありがとうございます。

なんとかする方法

スライドにも書いてますけど、
  1. $var * 10 ^ $num してから小数点以下を 切り捨ててテストする
    • $num 桁までの精度が保証されるはず
  2. 採択域を設定して、 両者の差がその範囲内かを テストする
  3. 正規表現を用いて小数点以下の桁数を制限してテストする
  4. sprintf() を用いて小数点以下の桁数を制限してテストする
なんかが考えられると思います。

本題

4 の方法である「sprintf() を用いて小数点以下の桁数を制限してテストする」方法をサポートするモジュールを書きました。

Test::LimitDecimalPlaces
https://github.com/moznion/Test--LimitDecimalPlaces

PrePAN にも上げてみました。
PrePAN - Test::LimitDecimalPlaces

で、

PrePAN での反応曰く「Test::Number::Delta があるからいらねーんじゃね?」との事でした。

Test::Number::Delta は、テスト対象の2つの値の差を求めてその絶対値を取って、
その値が任意の数値より小さいかどうか、つまり採択域内かどうかをチェックするという
テストメソッドを提供するモジュールです。大変便利です。

ただ、T::N::Delta は小数点桁数で制限を行なってテストを実施するわけではないので、
僕が作ったTest::LimitDecimalPlaces とは挙動が異なる気がします。
なので「どうでしょう。僕のこのアプローチは無意味でしょうか」みたいな感じのコメントを返したら
見事になしのつぶてなので難渋しております。

まあ、実用上はT::N::Delta でなんとかなる気もするのでコメント通りな気もするんですが、実際どうなんでしょうか……
アドバイスを欲しております。