2010-11-02 73 views
18

Possible Duplicate:
How to determine if a decimal/double is an integer?Cách tốt nhất để kiểm tra xem cặp đôi có phải là số nguyên trong C# không?

Tôi có loại biến gấp đôi và muốn kiểm tra xem đó có phải là số nguyên không.

Tại thời điểm này tôi có

public bool CheckIfInteger(double number) 
{ 
    return number.ToString().Contains(".") == false; 
} 

Có cách nào tốt hơn?

CẬP NHẬT: Xin lỗi tôi không nhận ra khả năng nhầm lẫn, theo số nguyên tôi có nghĩa là số nguyên toán học, đó là số tự nhiên cùng với số âm của các số tự nhiên khác 0.

+8

Cách của bạn là nguy hiểm: nếu cài đặt vùng máy có "," làm dấu phân cách thập phân? Có vẻ như bạn có thể chọn từ các câu trả lời bên dưới. :) –

+0

Điều đầu tiên mà bạn quan tâm với phương pháp hiện tại bạn sử dụng là nó có thể không tính đến dấu tách thập phân có thể khác nhau tùy thuộc vào văn bản chuỗi hiện tại. Nếu bạn chọn một trong các lựa chọn thay thế từ các câu trả lời dưới đây, hãy cẩn thận với bất kỳ thứ gì xử lý số đầu vào dưới dạng chuỗi trước khi cho bạn kết quả ... đặc biệt nếu nó không tính đến dấu tách thập phân khác với "." –

+0

@Shadow: Trường hợp của bạn có thể được giải quyết bằng 'CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator'. Nhưng những gì về '((thập phân)) Int32.MaxValue + 1)'? Đó là một số thập phân không có dấu phân tách thập phân – abatishchev

Trả lời

29
return Math.Truncate(number) == number; 

Như đã đề cập trong các ý kiến, bạn có thể cần phải tính đến thực tế là một đại diện double số của bạn có thể không phải là một số nguyên chính xác. Trong trường hợp đó bạn sẽ cần phải cho phép đối với một số lỗi lề-of-:

double diff = Math.Abs(Math.Truncate(number) - number); 
return (diff < 0.0000001) || (diff > 0.9999999); 
+7

Tuy nhiên, hãy lưu ý các vấn đề về độ chính xác của dấu phẩy động: với 'double number = 100.0 * (8183.23 - 6695.37)' bạn sẽ nhận được 'false' bằng phương thức này. –

6

Hãy thử:

public bool CheckIfInteger(double number) 
{ 
    return ((double) (int) number == number); 
} 

Hoặc đẹp:

public bool CheckIfInteger(double number) 
{ 
    return (Math.Floor(number) == number); 
} 
+0

Tại sao bạn cast int lại để tăng gấp đôi? – nawfal

24

Nếu bạn muốn kiểm tra một Integer, điều này sẽ làm điều đó:

public bool IsInteger(double number) 
{ 
    return (number % 1 == 0); 
} 

Nếu bạn thêm muốn kiểm tra xem số có thể được chuyển đổi thành Int32:

không
public bool IsInt32(double number) 
{ 
    return (number % 1 == 0) && number >= Int32.MinValue && number <= Int32.MaxValue; 
} 
+3

điều này sẽ không hoạt động trong trường hợp giá trị tăng gấp đôi lớn, phạm vi giá trị của gấp đôi lớn hơn giá trị của int. TryParse sẽ cung cấp cho bạn false vì phạm vi nhưng mod của bạn sẽ trả về true. Hãy dùng thử với double.MaxValue – BrokenGlass

+0

Cảm ơn ghi chú đã cập nhật câu trả lời của tôi. –

+0

@BrokenGlass, @Tim: Câu hỏi cho biết "số nguyên", không phải là "int" hoặc "Int32". Logic ban đầu của Tim là chính xác ở chỗ nó khớp với những gì OP cố gắng trong câu hỏi, trả về true cho bất kỳ số nguyên 'double', ngược lại sai. (Lý tưởng là OP nên làm rõ liệu chúng có nghĩa là 'Int32' hoặc chỉ số nguyên.) – LukeH

4

Tôi muốn sử dụng TryParse:

double value = 2.0; 
    int number; 
    bool result = Int32.TryParse(value.ToString(), out number); 
0

tôi sử dụng phương pháp mở rộng chuỗi sau đó kiểm tra đối với một mô hình RegEx

public static bool IsInteger(this string inputString) 
    { 
     Regex regexInteger = new Regex(@"^[-]?\d+$"); 
     Match m = regexInteger.Match(inputString); 
     return m.Success; 
    } 
+5

điều này sẽ không hoạt động trong nhiều trường hợp, bao gồm tràn, phạm vi giá trị gấp đôi lớn hơn giá trị của int. Bây giờ bạn có hai vấn đề. – BrokenGlass

+0

Nhận xét công bằng - đã đồng ý – Madeleine

+1

Điều này cũng sẽ thất bại khi một số âm không được biểu thị bằng -1, nhưng là (1)? –

15

Cạm bẫy khi làm việc với biểu diễn chuỗi là ngôn ngữ được sử dụng và bạn phải chăm sóc các vấn đề làm tròn. 0.999999999 có thể được coi là số nguyên 1 trong hầu hết các trường hợp. Dưới đây là một đoạn nhỏ có tính làm tròn lỗi:

Math.Abs(number - Math.Round(number)) < EPSILON 

nơi EPSILON là một giá trị gấp đôi là đủ nhỏ cho mục đích của bạn 0,00001 ví dụ

Xem thêm này đối với một số thông tin hơn: http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx

+5

+1 để đề cập đến epsilon. – Polyfun

2
public static bool CheckIfInteger(double number) 
    { 
     return number - Math.Truncate(number) == 0; 
    } 
+2

Làm thế nào về số == Math.Truncate (số)? – JohannesH

2

Tôi nghĩ rằng một câu hỏi hay hơn là: Làm thế nào tôi có thể biết liệu một đôi là đủ gần với một số nguyên được coi là một số nguyên cho mục đích của tôi? Bởi vì nếu không, bạn nhất định chạy vào sự mơ hồ. Vì vậy, tôi muốn giới thiệu một cái gì đó như thế này:

return Math.Abs(someDouble - Math.Round(someDouble)) < TOLERANCE; 
1

Tôi thích ý tưởng của abatishchev khi sử dụng CurrentCulture.

return number.ToString().Contains(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator) == false; 

Điều này không giải quyết được vấn đề epsilon (mà tôi thậm chí không cân nhắc ban đầu)?

Các vấn đề liên quan