Cách kiểm tra nếu số kép là số nguyên


165

có khả năng làm cái này không?

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
}

Tôi biết mã có lẽ không đi bất cứ điều gì như thế, nhưng làm thế nào không cho nó đi?


1
C # nhưng tương tự trong Java: stackoverflow.com/a/4077262/284240 ( Integer.MAX_VALUE )
Tim Schmelter

1
Bạn sẽ đạt được gì từ điều này? doubleintđược biểu diễn trong bộ nhớ khác nhau và bạn sẽ sử dụng cái này hoặc cái kia dựa trên bối cảnh xử lý bộ nhớ của bạn.
Makoto

@Legend, tôi sẽ làm như bạn đề nghị; Bạn có tình cờ biết làm thế nào% 1 so sánh hiệu quả-khôn ngoan với Math.floor (biến) mà người dùng khác đề xuất không?
G. Bạch

3
@Makoto Đó là một chương trình để tìm kiếm bộ ba pygatorean. Căn bậc hai đôi khi có thể gấp đôi, nhưng đồng thời đôi khi chúng cũng có thể là xen kẽ. Bạn hiểu ý tôi là gì?
JXPheonix

@JXPheonix: Vì vậy, các giá trị có thể là giá trị dấu phẩy động hoặc giá trị nguyên. Có ý nghĩa.
Makoto

Câu trả lời:


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

Cái này kiểm tra xem giá trị làm tròn của double có giống với double không.

Biến của bạn có thể có giá trị int hoặc double và Math.floor(variable)luôn có giá trị int, vì vậy nếu biến của bạn bằng Math.floor(variable)thì nó phải có giá trị int.

Điều này cũng không hoạt động nếu giá trị của biến là vô hạn hoặc vô hạn âm do đó thêm 'miễn là biến không vô hạn' vào điều kiện.


3
"Nếu đối số là NaN hoặc vô cực hoặc 0 dương hoặc 0 âm, thì kết quả giống như đối số." docs.oracle.com/javase/6/docs/api/java/lang/ triệt
Tim Schmelter

2
@TimSchmelter: bắt tốt. Cũng đáng lưu ý rằng NaN không bằng bất cứ thứ gì (kể cả chính nó) nhưng +/- Inf tương đương với chính nó - vì vậy có hai trường hợp cạnh!
maerics

Cả Skon và Fouad đều đăng câu trả lời tốt hơn nhiều.
Joel Christophel

@JoelChristophel: Tôi không đồng ý. Đây là một cách tốt vì nó giúp loại bỏ nguy cơ tràn kiểu. Điều duy nhất tôi không thích là sự khẳng định rằng biến là một intnếu ifđánh giá true.
Bathsheba

@Bathsheba (Double.POSITIVE_INFINITY% 1) == 0 và đối tác phủ định của nó đều đánh giá là sai.
Joel Christophel

222

Hoặc bạn có thể sử dụng toán tử modulo:

(d % 1) == 0


2
Tôi thực sự yêu thích sự đơn giản của giải pháp này. Nó vừa dễ đọc vừa dễ thực hiện.
krispy

1
Giải pháp rất trực quan
Daniel San

3
Về mặt tính toán, nó có nhanh hơn Math.rint(d)không?
iTurki

2
Vâng, điều này thật tuyệt, nhưng lưu ý rằng đây là một giải pháp Java và không được xác định rõ cho âm dtrong C và C ++.
Bathsheba

4
Trong Sonar, điều này tạo ra một vấn đề "Không nên thực hiện các bài kiểm tra đẳng thức với các giá trị dấu phẩy động".
Julio D

86

Quả ổi : DoubleMath.isMathematicalInteger. (Tiết lộ: Tôi đã viết nó.) Hoặc, nếu bạn chưa nhập Guava, x == Math.rint(x)là cách nhanh nhất để làm điều đó; rintđược đo nhanh hơn floorhoặc ceil.


3
Không biết về Math.rint Bạn đã đúng. Nó nhanh hơn Math.floor
Lenny Markus

Đây có phải là cách nào đó thích hợp hơn với ví dụ đúc của Eng.Fouad?
Joel Christophel

@JoelChristophel: Vâng. Không phải tất cả các phép nhân đôi với các giá trị nguyên đều nằm trong phạm vi int hoặc thậm chí dài, do đó phép thử sẽ không hoạt động trên chúng.
Louis Wasserman

Gotcha. Sau đó (d% 1) == 0 vẫn còn hiệu lực.
Joel Christophel


6

Hãy thử cách này

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

ví dụ:

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

do đó 12.9 không phải là số nguyên, tuy nhiên

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

do đó 12.0 là số nguyên


3

Đây là phiên bản cho 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;
    }
}

Để chuyển đổi Doublesang Integer:

Integer intVariable = variable.intValue();

3

Xem xét:

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

Điều này dính vào lõi Java và tránh sự so sánh bằng nhau giữa các giá trị dấu phẩy động ( ==) được coi là xấu. Điều isFinite()này là cần thiết vì rint()sẽ truyền qua các giá trị vô cực.



3

Đây là một giải pháp tốt:

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

Tại sao (bool)diễn viên?
xdavidliu

1
@xdavidliu Không cần điều đó. Chúng ta có thể bỏ qua nó.
Nitish

2

Tương tự như câu trả lời của SkonJeet ở trên, nhưng hiệu suất tốt hơn (ít nhất là trong 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);
}

Một triển khai đúng hơn sẽ trả về false và bạn sẽ phải viết một phương thức khác lấy int làm đối số và trả về true. : D
alfa

0

bạn có thể thử theo cách này: lấy giá trị nguyên của số kép, trừ giá trị này khỏi giá trị kép ban đầu, xác định phạm vi làm tròn và kiểm tra xem số tuyệt đối của giá trị kép mới (không có phần nguyên) lớn hơn hay nhỏ hơn phạm vi xác định. nếu nó nhỏ hơn bạn có thể dự định nó là một giá trị nguyên. Thí dụ:

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

Nếu bạn gán cho d giá trị 33,15 thì phương thức trả về true. Để có kết quả tốt hơn, bạn có thể gán các giá trị thấp hơn cho testRange (dưới dạng 0,0002) theo ý của bạn.


0

Cá nhân, tôi thích giải pháp hoạt động modulo đơn giản trong câu trả lời được chấp nhận. Thật không may, SonarQube không thích các bài kiểm tra đẳng thức với các điểm nổi mà không đặt độ chính xác tròn. Vì vậy, chúng tôi đã cố gắng tìm một giải pháp phù hợp hơn. Đây là:

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

Remainder(BigDecimal)trả về một BigDecimalcó giá trị là (this % divisor). Nếu cái này bằng 0, chúng ta biết không có điểm nổi.


0

Giải pháp đơn giản của tôi:

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

-1

Đây là một giải pháp:

float var = Your_Value;
if ((var - Math.floor(var)) == 0.0f)
{
    // var is an integer, so do stuff
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.