TL;DR
flutter×dartでアンドロイドアプリの電卓を作りました。既存の電卓アプリと違うのは、modが使えます。関数電卓ではないですが。
https://play.google.com/store/apps/details?id=com.chatram.calc_app
なぜ作ったか
ネイティブアプリを作ってみたかったのと、クロスプラットフォームのflutterってどうなの?と思ったので作ってみた。
例
デザインは自分のアンドロイドにプリインストールされていた電卓アプリを参考にしました。
仕組み
計算部分
static String Execute() {
var _result = Decimal.parse('0.0');
try {
_list_number.add(Decimal.parse(_buffer));
if (_list_number.length == 0) return '0';
_result = _list_number[0];
_list_number.removeAt(0);
for (int i = 0; i < _list_operand.length; i++) {
if (_list_operand[i] == '+')
_result += _list_number[0];
else if (_list_operand[i] == '-')
_result -= _list_number[0];
else if (_list_operand[i] == '×')
_result *= _list_number[0];
else if (_list_operand[i] == '÷')
_result = (_result / _list_number[0])
.toDecimal(scaleOnInfinitePrecision: 17);
else if (_list_operand[i] == 'mod')
_result %= _list_number[0];
else
return 'e';
_list_number.removeAt(0);
}
} catch (e) {
_list_number.clear();
_list_operand.clear();
_list.clear();
_buffer = '';
return '';
}
_list_number.clear();
_list_operand.clear();
_list.clear();
_buffer = '';
return _result.toString();
}
入力を数字とオペランドに分けてそれぞれ前から順に計算して結果を算出していきます。
エラー処理として、計算のどこかで事故ったり変な入力があったら、バッファをオールデリートして最初の入力前の状態になります。
感のいい方は気づいたかもしれませんが、この電卓は昔の電卓のように前から順に計算してしまうので、掛け算割り算が優先されません。
あとマイナスの計算はできません。
詰まったところ
- decimalを使わないと計算結果がブレるところ
既知の方は多いと思いますが、他の言語でもよく見られる挙動で、普通にfloatとかdoubleを使ってしまうと、入力された数字を一回2進数に変換して計算して、それをreturnするときに10進数に戻しているため、0.1+0.2=>0.30000000000000004
みたいになってしまいます。
- 数字にカンマを入れるところ
意外とこいつが曲者です。理由は主に2つで、
-
入力された数字を一回何桁かチェックして、3桁ごとにカンマを入れてやる実装をするのですが、少数点以下を検知しないようにする面倒さ。
-
入力途中の数字にもカンマを適用する実装にしたため、入力ごとにこの操作をして、挙げ句計算するクラスメソッドに投げるときにカンマをデリートして、計算結果にもう一度カンマを追加するというひどい仕様になってしまったため。(よい方法が思いつかなかった)
おそらく開発の8割くらいがここに吸われました。後悔はしていません。
最後に
ここまで読んでくれてありがとうございます!
興味があったら使ってみてください!
https://play.google.com/store/apps/details?id=com.chatram.calc_app
小言
android studioが僕のpcでエミュレータまで動かすと爆熱もっさり挙動だったので、VSCodeに変えたら楽になりました。以上です。
使ってたプラグイン
https://github.com/ppmasa8/VSCode-settings#extensions