質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

Javaの電卓アプリの計算結果が全て足し算になってしまいます。

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 689

score 1

前提・実現したいこと

足し算以外の計算の処理をさせたい。

参考にしたサイト
https://qiita.com/Hori-Masayuki/items/ee14a3964e53b4a8994d

AndroidStudioのJavaで電卓アプリを作成しています。
電卓の画面上に式を表示させることはできたのですが、肝心の「=」を押すと、掛け算も割り算も引き算も足し算になってしまいます。
エラーも出ていないため、どこを直せば動くようになるのかがわかりません。
計算を正しく実行させるにはどのようにすればよろしいでしょうか?

整数の足し算、引き算、掛け算、割り算のみの単純なアプリです。

発生している問題・エラーメッセージ

エラーメッセージ


なし

該当のソースコード

イコールのボタンを押した後に処理される部分です。

case R.id.equal:
                double tmp;
                double numResult = 0;
                //最終的な計算結果を取得する
                //まず文字列にして取得
                String TextFormula = formula.getText().toString();
                //数値がリストに入っていく
                List<String> nums = Arrays.asList(TextFormula.split("[\\+\\-×÷]", -1));

                    // 全て足し算の形に変換 size格納されている要素数
                    for (int i = 0; i < symbols.size(); i++) {

                        switch (symbols.get(i)) {
                            case "×":
                                //numsのi番目とi+1番目をかけたものを代入する ex)8*9=0+72 
                                //Double.parseDouble("変換したい文字列")引数で与えた文字列をdouble型に変換するメソッド
                                tmp = Double.parseDouble(nums.get(i)) * Double.parseDouble(nums.get(i + 1));
                                //numsのi番目に0をセット
                                nums.set(i, "0");
                                //numsのi+1番目にさっき計算したものを文字列に変換してセット
                                nums.set(i + 1, String.valueOf(tmp));
                                break;

                            case "÷":
                                tmp = Double.parseDouble(nums.get(i)) / Double.parseDouble(nums.get(i + 1));
                                nums.set(i, "0");
                                nums.set(i + 1, String.valueOf(tmp));
                                break;

                            case "−":
                                nums.set(i + 1, String.valueOf(Double.parseDouble(nums.get(i + 1)) * -1));
                                break;
                        }
                    }
                    //numsを一つ一つnumで受け取る
                    for (String num : nums) {
                        //numResult
                        numResult += Double.parseDouble(num);
                    }
                    //テキストビューに出力
                    result.setText(String.valueOf(numResult));
                break;
        }
    }
}
Java
ソースコード


package com.example.calculator;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    TextView formula, result;
    List<String> symbols;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //これはonCreateの中に書く
        //数字ボタンを取得
        findViewById(R.id.number0).setOnClickListener(this);
        findViewById(R.id.number1).setOnClickListener(this);
        findViewById(R.id.number2).setOnClickListener(this);
        findViewById(R.id.number3).setOnClickListener(this);
        findViewById(R.id.number4).setOnClickListener(this);
        findViewById(R.id.number5).setOnClickListener(this);
        findViewById(R.id.number6).setOnClickListener(this);
        findViewById(R.id.number7).setOnClickListener(this);
        findViewById(R.id.number8).setOnClickListener(this);
        findViewById(R.id.number9).setOnClickListener(this);
        //それ以外のボタンを取得
        findViewById(R.id.divided).setOnClickListener(this);
        findViewById(R.id.times).setOnClickListener(this);
        findViewById(R.id.minus).setOnClickListener(this);
        findViewById(R.id.plus).setOnClickListener(this);
        findViewById(R.id.equal).setOnClickListener(this);
        findViewById(R.id.wasa).setOnClickListener(this);
        findViewById(R.id.clear).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //電卓の処理

        //メッセージを表示するtextViewオブジェクトを取得
        TextView formula = findViewById(R.id.formula);
        TextView result = findViewById(R.id.result);

        //String型でArrayListを宣言
        ArrayList<String> symbols = new ArrayList<String>();

        //タップされた画面部品のidの値を取得
        //idのR値に応じて処理を分岐
        int id = v.getId();

        //押されたボタンごとに処理を分岐
        switch (id) {
            case R.id.number0:
                //途中式を取得して途中式に押されたものを追加
                formula.setText(formula.getText().toString() + "0");
                break;

            case R.id.number1:
                formula.setText(formula.getText().toString() + "1");
                break;

            case R.id.number2:
                formula.setText(formula.getText().toString() + "2");
                break;

            case R.id.number3:
                formula.setText(formula.getText().toString() + "3");
                break;

            case R.id.number4:
                formula.setText(formula.getText().toString() + "4");
                break;

            case R.id.number5:
                formula.setText(formula.getText().toString() + "5");
                break;

            case R.id.number6:
                formula.setText(formula.getText().toString() + "6");
                break;

            case R.id.number7:
                formula.setText(formula.getText().toString() + "7");
                break;

            case R.id.number8:
                formula.setText(formula.getText().toString() + "8");
                break;

            case R.id.number9:
                formula.setText(formula.getText().toString() + "9");
                break;

            case R.id.plus:
                //足し算
                formula.setText(formula.getText().toString() + "+");
                //リストの最後に要素を追加
                symbols.add("+");
                break;

            case R.id.minus:
                //引き算
                formula.setText(formula.getText().toString() + "−");
                symbols.add("−");
                break;

            case R.id.divided:
                //割り算
                formula.setText(formula.getText().toString() + "÷");
                symbols.add("÷");
                break;

            case R.id.times:
                //掛け算
                formula.setText(formula.getText().toString() + "×");
                symbols.add("×");
                break;

            case R.id.wasa:
                //+-を変更する

            case R.id.clear:
                //結果表示画面をクリアにする
                formula.setText("");
                result.setText("");
                symbols.clear();
                break;

            case R.id.equal:
                double tmp;
                double numResult = 0;
                //最終的な計算結果を取得する
                //まず文字列にして取得
                String TextFormula = formula.getText().toString();
                //数値がリストに入っていく
                List<String> nums = Arrays.asList(TextFormula.split("[\\+\\-×÷]", -1));

                //例外が起きそうなところをtryでかこむ
                try {
              /*  //-5-5ができるようにする numsに設定されていた空白に0をセットしてあげる
                if ((nums.get(0).length() == 0) && (symbols.get(0) == "-")) {
                    nums.set(0, "0");
                }*/

                    // 全て足し算の形に変換 size格納されている要素数
                    for (int i = 0; i < symbols.size(); i++) {

                        switch (symbols.get(i)) {
                            case "×":
                                //numsのi番目とi+1番目をかけたものを代入する ex)8*9=0+72 
                                //Double.parseDouble("変換したい文字列")引数で与えた文字列をdouble型に変換するメソッド
                                tmp = Double.parseDouble(nums.get(i)) * Double.parseDouble(nums.get(i + 1));
                                //numsのi番目に0をセット
                                nums.set(i, "0");
                                //numsのi+1番目にさっき計算したものを文字列に変換してセット
                                nums.set(i + 1, String.valueOf(tmp));
                                break;

                            case "÷":
                                tmp = Double.parseDouble(nums.get(i)) / Double.parseDouble(nums.get(i + 1));
                                nums.set(i, "0");
                                nums.set(i + 1, String.valueOf(tmp));
                                break;

                            case "−":
                                nums.set(i + 1, String.valueOf(Double.parseDouble(nums.get(i + 1)) * -1));
                                break;
                        }
                    }
                    //numsを一つ一つnumで受け取る
                    for (String num : nums) {
                        //numResult
                        numResult += Double.parseDouble(num);
                    }
                    //テキストビューに出力
                    result.setText(String.valueOf(numResult));
                    //tryの続き
                } catch (Exception e) {
                    Log.e("エラー", e.getMessage());
                }
                break;
        }
    }
}


```

以上です。よろしくお願いいたします。

試したこと

カッコの位置の移動
処理を少なくして実行
再起動

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kaina

    2021/06/08 09:57

    デバッグの仕方を知らないなら以下のページでデバッグのやり方を学習して下さい。
    記事は2017年と多少古いですが、デバッグのやり方は大差ないと思います。
    https://techacademy.jp/magazine/2441

    キャンセル

  • dodox86

    2021/06/08 10:03

    参考にされること自体は良いと思いますが、コードの1行1行の内容、処理について理解されていますか?

    キャンセル

  • Asukaa

    2021/06/08 21:35

    >>hoshi-takanoriさん
    丁寧に教えていただきありがとうございます。
    ログを取ったところ、symbolsに何も格納されていないことがわかりました。
    すごく助かりました。ありがとうございます。

    >>kainaさん
    コメントありがとうございます。
    教えていただいたサイトとてもわかりやすいです。
    今回でデバックはマスターします。
    ありがとうございました。

    >>dodox86さん
    コメントありがとうございます。
    はい。エラーを解消するために読み込んでいくうちに説明できるようになりました。笑 ありがとうございました。

    キャンセル

回答 3

checkベストアンサー

+2

これだけの問題ではなさそうですが、「-」と「−」が混在しているように見受けられます。
これによって「-」を含む計算時は、TextFormulaの「-」前後の数字が分割されていない状態になっており、計算過程にも影響があります。
但し、これを解消しても当該エラーは解決しないと思われるので、別の要因があると思います。

splitの引数の[]内 こちらは「-」Unicode 002D:よく使われる一般的な半角ハイフンマイナス

//数値がリストに入っていく
                List<String> nums = Arrays.asList(TextFormula.split("[\\+\\-×÷]", -1));


""で囲まれてる箇所「−」 Unicode 2212 :マイナスではあるけど上記とは別物
※(nums.get(i + 1)) * -1) の-1 は算術演算子としての正しいマイナス

case R.id.minus:
                //引き算
                formula.setText(formula.getText().toString() + "−");
                symbols.add("−");
                break;
                            case "−":
                                nums.set(i + 1, String.valueOf(Double.parseDouble(nums.get(i + 1)) * -1));
                                break;


プログラム内ではマイナスの算術演算子としてではなくマイナスを表す記号として使われているので、どちらかに統一すれば機能するとは思います。
(Unicode 2212に統一する場合は 正規表現でエスケープする必要がないので下記のようにする必要があります)

List<String> nums = Arrays.asList(TextFormula.split("[\\+-×÷]", -1));

但しミスを防ぐためにも一般的な「-」Unicode 002D:半角ハイフンマイナスに統一すべきでしょう。

余談ですが、エディターのフォントにMSゴシックだったりを使っているのであれば、
違いがわかりにくいので適切なフォントに変更することをお奨めします。
イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/06/08 21:24

    コメントありがとうございます。
    ご指摘の通り-の処理ができなくなり、全部揃えたところうまく行きました。
    エディターのフォントを変えることができるのは知らなかったので、早速変えてみます。
    ありがとうございました。

    キャンセル

+2

                    //numsを一つ一つnumで受け取る
                    for (String num : nums) {
                        //numResult
                        numResult += Double.parseDouble(num);
                    }
                    //テキストビューに出力
                    result.setText(String.valueOf(numResult));


なんかここで全部足し込んで出力してますが、これのことかな

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/06/08 21:28

    コメントありがとうございます。
    ここは足し算以外の計算を足し算の処理に直した後に足している処理なのですが、ここだけ動いていたため、足し算だけができているという状態でした。
    ありがとうございました。

    キャンセル

0

解決いたしました。

 //String型でArrayListを宣言
        ArrayList<String> symbols = new ArrayList<String>();


このsymbolsを格納するリストがonClick(View v)の中に入っていたことにより、ボタンが押されるたびに新しくnewされてしまい、-×÷が保存されていないことが原因でした。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


の下に移したところ動くようになりました。
Activityのライフサイクルを考えることが不足していました。

ご回答いただいた方々、本当にありがとうございました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/06/08 21:35

    y_waiwaiさんとCrimson_Tideさんのどちらも参考になったはずで、自己解決ではありませんよね?

    ベストアンサーは変更することが出来ます。
    以下のヘルプに書いてある通り、ベストアンサーは一番参考になった回答に付けてあげて下さい。
    https://teratail.com/help#resolve-question

    キャンセル

  • 2021/06/08 21:40

    やり方がよくわからず大変失礼いたしました。
    変更させていただきました。
    教えていただき、ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る