Firebaseの技術情報サイト

Firebaseの技術情報サイト

Firebase活用の為の技術情報サイトです

足し算以外もできるようにする

足し算以外もできるようにする

穴埋め形式の数式のフォームを使って足し算をするプログラムを紹介しましたが、同じ要領で、引き算、掛け算、割り算もサポートできるとさらに便利です。この記事では、足し算のプログラムを拡張して、整数の子息演算をできるようにした例を紹介します。

目次
演算子を選べるように変更する
演算子の変更を反映する
計算の処理は?
例外処理
まとめ

演算子を選べるように変更する

足し算のアプリでは、計算できるのは足し算だけだったので、フォームには「+」を固定で表示していました。 この部分に変更を加えて、必要な演算子を選択できるようにすれば、引き算、掛け算、割り算もサポートできるようにできます。

これには、HTML の記述を変更してフォームを変更する必要があります。

<label>+</label>

を以下のように変更します。

<select onchange="operatorChanged(event)">
  <option>+</option>
  <option>-</option>
  <option>*</option>
  <option>/</option>
</select>

HTML の「select」タグを使って、選択肢は、「option」タグで記述するだけです。

演算子の変更を反映する

プログラム側でやることは三つです。

  • 初期状態の演算子を設定する (最初にフォーム上で表示されている演算子をセットする)
  • 演算子の変更を検出して、現在選択されている選択肢を更新する
  • 「Calcullate」ボタンがクリックされたら必要な処理を呼び出す

現在どの演算子が選択されているかを知る必要があります。実装方法は幾つかありますが、今回は選択が変更される度に現在選択されている演算子を更新する方法を採用した例を紹介します。

これには、現在選択されている演算子を保存する変数「operator」を用意して管理します。 まずは、最初にフォームで表示されている演算子が何も変更しない場合の値に真ります。今回の例では、「+」になりますので、これを最初にあらかじめセットする必要があります。

let operator = "+";

あとは、選択されている演算子が変更される度にこの変数を更新するようにすれば良い事になります。 更新の変更は、「onchange」を使って、処理(関数)を呼び出せるようにすれば完了です。選択されている演算子は、イベントのオブジェクトから取得できます。

function operatorChanged(e) {
  operator = e.target.value;
}

別の実装方法としては、「Calculate」ボタンが押された際に、選択されている演算子を取得して、必要な処理を呼び出す方法も可能です。 この方法では、現在選択されている演算子を保持する変数は必要なくなります。また、演算子が変更される度に更新のための処理を呼び出す必要がなくなります。要は全ての処理を「Calculate」ボタンが押された時に行うという方法です。

このようなシンプルなアプリの場合、どちらの方法でもあまり大きな差はありません。

プログラムの規模が大きくなった場合は、個々の処理を別々に分けた方が、プログラム全体の管理がやりやすい場合が多くなるので、今回の例のような実装をする場合が多くなると思います。

計算の処理は?

あとは、「Calculate」ボタンがクリックされたら、計算の処理を呼び出すだけです。 この例でサポートするのは:

  • 足し算「+」
  • 引き算「-」
  • 掛け算「*」
  • 割り算「/」 の四つの演算です。

これを、選択されている演算子に応じて違うデータ処理を呼び出します。

function calculateEvent() {
  // Clears the output field
  resultField.value = "";
  const ope0 = parseInt(inputField0.value);
  const ope1 = parseInt(inputField1.value);
  let result = NaN;
  if (isNaN(ope0) || isNaN(ope1)) {
    alert("数値が入力されていません!");
  } else {
    switch (operator) {
      case "+":
        result = add(ope0, ope1);
        break;
      case "-":
        result = sub(ope0, ope1);
        break;
      case "*":
        result = mul(ope0, ope1);
        break;
      case "/":
        try {
          result = div(ope0, ope1);
        } catch {
          alert("Error: Divide by zero");
        }
        break;
      default:
        console.log("Unepected operator!");
        break;
    }
    resultField.value = result;
  }
}

Javascript の「switch 文」を使えば簡単に実現できます。 選択肢は、「+」、「-」、「*」、「/」の四つです。それ以外の選択肢は「default」になりますが、今回はフォームでこの四つ以外状態が選択される場合がないので、特に処理を明記していません。ただ、想定外の選択がされた場合にデバッグを簡単にするため、想定外の選択が起きたことがわかるようにしておくと便利です。

default:
          console.log("Unepected operator!")
          break;

通常は、この部分が実行される事はありませんが、万が一これが実行された場合は、デバッグの重要な情報になります。 多くの場合、フォームに選択肢を追加したり、演算子の初期値が正しく設定されていないなどのバグが想定されます。

例外処理

今回の例では、整数以外のデータの入力を禁止しているので、基本的にデータ処理でエラーになるケースは限られています。 特に注意するのが、この例では、「0で割る」というケースです。 基本的に、通常のプログラミング言語では、「0で割るという処理」はサポートされていません。つまり、「答えがない」という状態が発生します。 これは、割り算特有の例外です。そこで、割り算の場合は、「0」で割る処理の場合は、例外を発生するようにしています。

function add(a, b) {
  return a + b;
}
function sub(a, b) {
  return a - b;
}
function mul(a, b) {
  return a * b;
}
function div(a, b) {
  if (b === 0) {
    throw "Divide by zero";
  } else {
    return a / b;
  }
}

割り算の呼び出し側では、例外があった場合の処理を以下のように記述しています。

try {
  result = div(ope0, ope1);
} catch {
  alert("Error: Divide by zero");
}

このように実装することで、利用者にサポートしていない計算が実行された場合に通知できるようにしています。

まとめ

今回は、プログラムの拡張の例を紹介しました。 ユーザーインターフェースのフォームを変更して他の演算子を選べるようにして、演算子毎のデータ処理を追加すれば足し算だけではなく、引き算、割り算、掛け算、割り算も簡単に処理できるようになります。

もう一点は、プログラミング言語あるいは、CPU による制約でサポートしていない例外的な結果の処理が必要になるという例も紹介しています。今回は、「0で割る」という処理ですが、この例では実装していませんが、プログラミング言語と CPU で決めている数の範囲外の結果になる場合も実は存在します。オーバーフローとかアンダーフローと呼ばれる例外です。現在の CPU では、この数字の範囲は現実的な計算では、起きる可能性は少なくなりますが、発生する可能性はあります。厳密に処理するのであれば、こうしたオーバーフローやアンダーフローの処理も必要になります。 (この例では、発生する可能性が低いため簡単に実装するという観点で省いています)

一方で、「0」で割るというケースは、入力の誤りでも発生する可能性があるので、処理に入れています。