doubleが整数かどうかをテストする方法


165

これは可能ですか?

double variable;
variable = 5;
/* the below should return true, since 5 is an int. 
if variable were to equal 5.7, then it would return false. */
if(variable == int) {
    //do stuff
}

私はコードがおそらくそのようなことをしないことを知っています、しかしそれどのように行くのですか?


1
C#ですがJavaでも同様です:stackoverflow.com/a/4077262/284240Integer.MAX_VALUE
Tim Schmelter

1
あなたはこれから何を得るでしょうか? doubleおよびintメモリ内での表現は異なり、メモリ処理のコンテキストに基づいてどちらかを使用します。

@レジェンド、私はあなたが提案したのと同じことをしたでしょう。%1が他のユーザーが提案したMath.floor(variable)と効率的に比較する方法を偶然知っていますか?
G.バッハ

3
@まことpygatorean triplesを探すプログラムです。平方根は2倍になることもありますが、同時に整数になることもあります。分かりますか
JXPheonix 2012年

@JXPheonix:したがって、値は浮動小数点値または整数値のいずれかになります。理にかなっています。
マコト

回答:


146
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) {
    // integer type
}

これは、doubleの切り捨てられた値がdoubleと同じかどうかをチェックします。

変数はintまたはdouble値を持つことができ、Math.floor(variable)常にint値を持つため、変数が等しい場合、変数はMath.floor(variable)int値を持つ必要があります。

これは、変数の値が無限または負の無限の場合にも機能しないため、「変数が無限でない限り」条件に追加されます。


3
「引数がNaNまたは無限大、正のゼロまたは負のゼロの場合、結果は引数と同じになります。」docs.oracle.com/javase/6/docs/api/java/lang/...
ティムSchmelter

2
@TimSchmelter:良いキャッチ。NaNは何も(それ自体を含む)等しくないことにも注意する必要がありますが、+ /-Infはそれ自体に等しいため、2つのエッジケースがあります。
maerics 2012年

SkonとFouadの両方がはるかに優れた回答を投稿しました。
Joel Christophel

@JoelChristophel:同意しません。これは、型オーバーフローのリスクを排除するため、良い方法です。私が気に入らなかった唯一のことは、変数がであるintif評価された場合の変数であるという主張でしたtrue
バトシェバ

@Bathsheba(Double.POSITIVE_INFINITY%1)== 0とその負の対応は両方ともfalseと評価されます。
Joel Christophel

222

または、モジュロ演算子を使用することもできます。

(d % 1) == 0


2
私はこのソリューションのシンプルさを本当に気に入っています。読みやすく、実装も簡単です。
クリスピー2014

1
非常に直感的なソリューション
Daniel San

3
計算に関して、それはより速いですMath.rint(d)か?
iTurki、2015年

2
はい、これはいいですが、これはJavaソリューションでありd、CおよびC ++のネガティブに対して明確に定義されていないことに注意してください。
バトシェバ

4
Sonarでは、これにより「浮動小数点値を使用して等価テストを行うべきではない」という問題が発生します。
フリオD

86

グアバ:DoubleMath.isMathematicalInteger。(開示:私が作成しました。)または、まだGuavaをインポートしていない場合x == Math.rint(x)は、それが最も速い方法です。またはrintよりもかなり高速です。floorceil


3
Math.rintについて知りませんでした。Math.floorよりもはるかに高速です
Lenny Markus

これはEng.Fouadのキャストの例よりもどういうわけですか?
Joel Christophel

@JoelChristophel:はい。整数値を持つすべてのdoubleがintの範囲、またはさらにはlongであるとは限らないため、テストはそれらに対して機能しません。
Louis Wasserman

ゴッチャ。その後、(d%1)== 0はまだ有効です。
Joel Christophel


6

この方法を試してください、

public static boolean isInteger(double number){
    return Math.ceil(number) == Math.floor(number); 
}

例えば:

Math.ceil(12.9) = 13; Math.floor(12.9) = 12;

したがって、12.9は整数ではありませんが、それでも

 Math.ceil(12.0) = 12; Math.floor(12.0) =12; 

したがって、12.0は整数です


3

ここでのバージョンだIntegerDouble

    private static boolean isInteger(Double variable) {
    if (    variable.equals(Math.floor(variable)) && 
            !Double.isInfinite(variable)          &&
            !Double.isNaN(variable)               &&
            variable <= Integer.MAX_VALUE         &&
            variable >= Integer.MIN_VALUE) {
        return true;
    } else {
        return false;
    }
}

に変換するDoubleにはInteger

Integer intVariable = variable.intValue();

3

考慮してください:

Double.isFinite (value) && Double.compare (value, StrictMath.rint (value)) == 0

これはコアJavaに固執し、==不良と見なされる浮動小数点値()間の等価比較を回避します。パススルーの無限大の値とisFinite()同様に、これが必要rint()です。



3

ここに良い解決策があります:

if (variable == (int)variable) {
    //logic
}

なぜ(bool)キャスト?
xdavidliu

1
@xdavidliuその必要はありません。無視できます。
Nitish

2

上記のSkonJeetの回答に似ていますが、パフォーマンスはより優れています(少なくともJavaでは)。

Double zero = 0d;    
zero.longValue() == zero.doubleValue()

1
public static boolean isInteger(double d) {
  // Note that Double.NaN is not equal to anything, even itself.
  return (d == Math.floor(d)) && !Double.isInfinite(d);
}

より正確な実装はfalseを返し、intを引数として取り、trueを返す別のメソッドを作成する必要があります。:D
アルファ

0

この方法で試すことができます:doubleの整数値を取得し、これを元のdouble値から減算し、丸め範囲を定義し、新しいdouble値(整数部分なし)の絶対数が、定義された範囲。小さい場合は整数値にすることができます。例:

public final double testRange = 0.2;

public static boolean doubleIsInteger(double d){
    int i = (int)d;
    double abs = Math.abs(d-i);
    return abs <= testRange;
}

dに値33.15を割り当てると、メソッドはtrueを返します。より良い結果を得るには、testRangeに低い値(0.0002として)を自由に割り当てることができます。


0

個人的に、私は受け入れられた答えで単純なモジュロ演算ソリューションを好みます。残念ながら、SonarQubeは、丸めの精度を設定せずに浮動小数点を使用した等価テストを好みません。そこで、私たちはより準拠したソリューションを見つけようとしました。ここにあります:

if (new BigDecimal(decimalValue).remainder(new BigDecimal(1)).equals(BigDecimal.ZERO)) {
    // no decimal places
} else {
    // decimal places
}

Remainder(BigDecimal)BigDecimal値がのを返します(this % divisor)。これがゼロに等しい場合、浮動小数点がないことがわかります。



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.