業務にて詰まった部分とその解決方法を簡単に紹介
発生した問題
不特定数の値のリストを全て加算するという処理を実行する場合なんかにfold
を使うことがあるかと思います
例えば、以下のようなリストがあったとします
final sumValueList = [1, 2, 3, 4, 5];
これを全て加算した結果を取得したい場合はfold
で以下のように記述します
final result = sumValueList.fold<int>(
0, (previousValue, element) => previousValue + element
); // 15
とまあ普通に使う分にはただ便利なだけで何ら問題ないfold
ですが、小数を含む計算をしていた時に問題が発生しました
その時に計算した値と結果は以下の通りです
final sumValueList = [99, 1.9, 1.9, 1.3, 1];
final result = sumValueList.fold<double>(
0, (previousValue, element) => previousValue + element
); // 105.10000000000001
めっちゃ桁が増えました
原因はシンプルに浮動小数の計算における仕様です
詳しくは解説しませんが、小数ごとのズレが累積していった結果表面化したのが上記の結果になります
解決策
この現象自体はどうしようもないので、発生した後に対処する必要があります
小数なので四捨五入するなりすれば解決しそうですが、今回実装していた仕様だと「小数第一位までの値を取得して表示する」というものなので、下手に計算を追加して結果が変わるようなことがあったら面倒なことになってしまいます
そこで役に立つのがtoStringAsFixed
です
これは小数を指定した桁数までで固定するといった挙動を実現してくれます
使い方は先ほどの計算結果の最後に付け加えるだけです
final sumValueList = [99, 1.9, 1.9, 1.3, 1];
final result = sumValueList.fold<double>(
0, (previousValue, element) => previousValue + element
).toStringAsFixed(1); // 105.1
表示したい部分まで取得することができました
小数の加減算を実装するときは、結果におかしなことが起きていないかを気をつけましょうという話でした