Bir çiftin bir tam sayı olup olmadığını test etme


166

Bunu yapmak mümkün mü?

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
}

Ben kod muhtemelen böyle bir şey gitmez biliyorum ama nasıl yok gitti?



1
Bundan ne elde edersiniz? doubleve intbellekte farklı şekillerde gösterilir ve bellek işleminizin içeriğine göre birini veya diğerini kullanırsınız.
Makoto

@Legend, önerdiğin gibi yapardım; % 1'in verimlilik açısından diğer kullanıcıların önerdiği Math.floor (değişken) ile nasıl karşılaştırıldığını tesadüfen biliyor musunuz?
G. Bach

3
@ Makoto Pygatorean üçlüleri bulmak için bir program. Kare kökler bazen çift olabilir, ancak aynı zamanda bazen interger olabilirler. Ne demek istediğimi anladın mı?
JXPheonix

@JXPheonix: Değerler kayan nokta değeri veya tam sayı değeri olabilir. Mantıklı.
Makoto

Yanıtlar:


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

Bu, çiftin yuvarlatılmış değerinin çiftle aynı olup olmadığını kontrol eder.

Değişkeninizin int veya çift değeri olabilir ve Math.floor(variable)her zaman int değeri olabilir, bu nedenle değişkeniniz eşitse Math.floor(variable)int değerine sahip olmalıdır.

Bu, değişkenin değeri sonsuz veya negatif sonsuzsa da işe yaramaz, bu nedenle koşula 'değişken sonsuz olmadığı sürece' eklenir.


3
"Bağımsız değişken NaN veya sonsuz veya pozitif sıfır veya negatif sıfır ise, sonuç bağımsız değişken ile aynıdır." docs.oracle.com/javase/6/docs/api/java/lang/…
Tim Schmelter

2
@TimSchmelter: iyi yakalama. NaN'ın (kendisi dahil) herhangi bir şeye eşit olmadığını, ancak +/- Inf'in kendisine eşit olduğunu da belirtmek gerekir - bu nedenle iki kenar vaka var!
maerics

Hem Skon hem de Fouad daha iyi cevaplar verdi.
Joel Christophel

@JoelChristophel: Kabul etmiyorum. Tip taşması riskini ortadan kaldırdığı için bu iyi bir yoldur. Ben sevmedim tek şey değişken bir iddiası oldu inteğer ifdeğerlendirir için true.
Bathsheba

@Bathsheba (Double.POSITIVE_INFINITY% 1) == 0 ve negatif muadili yanlış olarak değerlendiriliyor.
Joel Christophel

223

Veya modulo operatörünü kullanabilirsiniz:

(d % 1) == 0


2
Bu çözümün basitliğini gerçekten çok seviyorum. Hem okumak hem de uygulamak kolaydır.
krispy

1
Çok sezgisel çözüm
Daniel San

3
Hesaplama açısından, daha hızlı Math.rint(d)mı?
iTurki

2
Evet bu güzel, ama bunun bir Java çözümü olduğunu ve dC ve C ++ negatif için iyi tanımlanmadığını unutmayın .
Bathsheba

4
Sonar'da bu durum “kayan nokta değerleri ile eşitlik testleri yapılmamalıdır” sorununu doğurur.
Julio D

86

Guava: DoubleMath.isMathematicalInteger. (Açıklama: Yazdım.) Ya da, zaten Guava'yı ithal x == Math.rint(x)etmiyorsanız, bunu yapmanın en hızlı yolu; rintölçülebilir şekilde floorveya değerinden daha hızlıdır ceil.


3
Math.rint hakkında bilmiyordum. Math.floor'dan daha hızlı
Lenny Markus

Bu Eng.Fouad'ın döküm örneğine bir şekilde tercih edilebilir mi?
Joel Christophel

@JoelChristophel: Evet. Tamsayı değerlere sahip tüm çiftler int aralığında veya hatta uzun değildir, bu nedenle test bunlar üzerinde çalışmaz.
Louis Wasserman

Anladım. Sonra (d% 1) == 0 hala geçerlidir.
Joel Christophel

20
public static boolean isInt(double d)
{
    return d == (int) d;
}

6

Bu şekilde dene,

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

Örneğin:

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

dolayısıyla 12.9 olduğu değil yine de, tam sayı

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

dolayısıyla 12.0 tam sayıdır


3

İşte Integerve için bir sürüm Double:

    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;
    }
}

Dönüştürmek Doubleiçin Integer:

Integer intVariable = variable.intValue();

3

Düşünmek:

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

Bu, çekirdek Java'ya yapışır ve kayan nokta değerleri ( ==) arasında kötü olarak değerlendirilen bir eşitlik karşılaştırmasını önler . isFinite()Gerekli olan rint()geçiş olacak sonsuz değerleri.



3

İşte iyi bir çözüm:

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

neden (bool)oyuncular?
xdavidliu

1
@xdavidliu Buna gerek yok. Bunu görmezden gelebiliriz.
Nitish

2

SkonJeet'in yukarıdaki cevabına benzer, ancak performans daha iyi (en azından java'da):

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);
}

Daha doğru bir uygulama false değerini döndürür ve int'i argüman olarak alan ve true döndüren başka bir yöntem yazmanız gerekir. : D
alfa

0

bu şekilde deneyebilirsiniz: çiftin tamsayı değerini alın, bunu orijinal çift değerden çıkarın, bir yuvarlama aralığı tanımlayın ve yeni çift değerin mutlak sayısının (tamsayı kısmı olmadan) tanımlı aralık. daha küçükse, bir tamsayı değerdir. Misal:

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'ye 33.15 değerini atarsanız, yöntem true değerini döndürür. Daha iyi sonuçlar elde etmek için, takdirinize bağlı olarak testRange'a (0.0002 olarak) daha düşük değerler atayabilirsiniz.


0

Şahsen, kabul edilen cevapta basit modulo operasyon çözümünü tercih ediyorum. Ne yazık ki, SonarQube yuvarlak bir hassasiyet ayarlamadan kayan noktalı eşitlik testlerini sevmez. Bu yüzden daha uyumlu bir çözüm bulmaya çalıştık. İşte burada:

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

Remainder(BigDecimal)BigDecimaldeğeri olan bir değeri döndürür (this % divisor). Eğer bu sıfıra eşitse, kayan nokta olmadığını biliyoruz.


0

Benim basit çözümüm:

private boolean checkIfInt(double 
 value){
 return value - Math.floor(value) == 0;
 }

-1

İşte bir çözüm:

float var = Your_Value;
if ((var - Math.floor(var)) == 0.0f)
{
    // var is an integer, so do stuff
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.