【Java】小数点以下の値を持っているかを判断する

Java

はじめに

プログラミングの問題をパズル感覚で解くことがあるのですが、時折「小数点以下の値がある場合・・・」のような問題が出てくることがあるんですね。

その際、doubleの値に小数点以下の値が含まれているかどうかの判断方法を、毎度毎度google検索で検索しては脳みそから捨てて、、、を繰り返しているので、そのループをなくすために記事化&サンプルコードの作成をしてみたものです。

注意

  • doubleの値に小数点以下の値があるかどうか、の判定だけに注力しています。
    • 有無だけしか見ないため、小数点以下の値の正しさはまったく考慮していません。
    • 値の正しさを求めるのであれば、BigDecimalなどを使った解決法があるかと思います。

コード例

採用したコード

boolean変数に格納するために計算している箇所が、小数点以下の値の有無を判断するロジックになってます。

double d = 3.0 / 2.0;    // d = 1.5
boolean b = d % 1 != 0;  // b = true

流れは、

  • d % 1
    • 1で割った余りを取得します。小数点以下の値のみ抽出された結果が返ります。
  • d % 1 != 0
    • d % 1の結果と 0 を比較し、一致しなければtrue(=>小数点以下の値あり)となります。

サンプルコード

動作確認で使用したコードは以下となります。(利用する場合は、クラスなどは補完ください)

public static void main(String[] args) {
    double d = 3.0 / 2.0;     // = 1.5
    System.out.println(hasAfterTheDecimalPoint(d));
}

private static boolean hasAfterTheDecimalPoint(double d) {
    return d % 1 != 0;
}

ボツ案

ボツ1(動作しない)

小数点が結果に含まれていればいいなら、文字列に変えて”.”があるか調べればいいんじゃね?と考えて産み出されたコードがこちら。

double d = 3.0 / 2.0;
boolean hasDecimalPoint = String.valueOf(d).indexOf(".") != -1;

doubleの結果をprintlnすると分かるのですが、doubleを文字列変換すると、割り切れる数値であっても”.”が含まれます。

例:4.0 / 2.0 の結果をdoubleに代入 => 2.0

したがって、indexOf(“.”)の結果は必ず0以上の数値が返るため、常にtrue(小数点以下の値あり)となってしまいます。

ボツ2

文字列の解析に拘って産み出されたものが次のコードです。

double d = 3.0 / 2.0;
boolean hasAfterTheDecimalPoint = String.valueOf(d).matches("[\\d]+\\.0$") != -1;

このコードは、正規表現で”何らかの数字の繰り返し.0″終わりの値であるかをチェックするため、動作自体はします。

ただ、採用案に比べると簡単に書けてないですね。文字列への変換、正規表現の構文考案、正規表現のパターンコンパイルが都度発生するコードになっているので、無駄なコストもかかってしまいます。

(頻繁に使う正規表現であれば、事前にPattern.compile()することで、matchesのコストは少し下げられはします)

最後に

冒頭にも書きましたが、プログラミングの問題を解く際に使うケースがある程度ですが、それでも突然出てこられると戸惑うんですよね。「前も検索したな~」とか思いながら検索することもしばしば。

JavascriptだとNumber.isInteger()を使えば、今回の課題は一瞬でコード成立してしまうので、そういうのないかなぁとか調べてしまったり。

自作で考えるよ、となったときの一助になれば幸いです。

コメント

タイトルとURLをコピーしました