Chuyển một double thành int trong C #


101

Trong mã của chúng tôi, chúng tôi có một đôi mà chúng tôi cần chuyển đổi thành một int.

double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;

Bất cứ ai có thể giải thích cho tôi tại sao i1 != i2?

Kết quả mà tôi nhận được là: i1 = 9i2 = 8.


5
Math.Truncate(score)được thể hiện một cách rõ ràng hơn ý hơn(int)score
Lu55

3
Nhưng Math.Truncate trả về một đôi hoặc số thập phân, không phải là một int
Sergioet

Câu trả lời:


161

Convert.ToInt32vòng:

Giá trị trả về: làm tròn đến số nguyên có dấu 32 bit gần nhất. Nếu giá trị nằm giữa hai số nguyên, thì số chẵn được trả về; nghĩa là, 4,5 được chuyển đổi thành 4 và 5,5 được chuyển đổi thành 6.

... trong khi dàn diễn viên cắt ngắn :

Khi bạn chuyển đổi từ giá trị kép hoặc giá trị float sang kiểu tích phân, giá trị sẽ bị cắt bớt.

Cập nhật: Xem bình luận của Jeppe Stig Nielsen bên dưới để biết thêm những khác biệt (tuy nhiên, điều này sẽ không có tác dụng nếu scorelà một số thực như trường hợp ở đây).


6
Liên kết của bạn thực sự giải thích nó tốt nhất và nó không đơn giản như round vs truncate: Gõ: Giá trị System.Int32, được làm tròn đến số nguyên có dấu 32 bit gần nhất. Nếu giá trị nằm giữa hai số nguyên, thì số chẵn được trả về; có nghĩa là, 4.5 được chuyển đến 4, và 5,5 được chuyển đổi sang 6.
ericosg

@ericosg: Vâng, điều đó sẽ che giấu sự khác biệt nếu score8.5thay vì 8.6. Tôi đã cập nhật câu trả lời để bao gồm các trích dẫn. Cảm ơn các đầu vào.
Jon

5
Và nếu scoreNaNhoặc vô cùng hoặc hữu hạn nhưng nằm ngoài phạm vi của Int32, thì Convert.ToInt32sẽ ném ra một ngoại lệ. Truyền sẽ trả về một int, nhưng bạn sẽ không biết cái nào (trong cách triển khai của tôi là Int32.MinValue) vì bạn đang ở trong uncheckedngữ cảnh. (Nếu bạn ở trong checkedbối cảnh, dàn diễn viên cũng sẽ có một ngoại lệ trong những trường hợp này.)
Jeppe Stig Nielsen

@JeppeStigNielsen: Cảm ơn bạn đã đóng góp ý kiến, tôi đã cập nhật câu trả lời để đề cập đến vấn đề này.
Jon

Đẹp. Nhưng tôi nghĩ rằng Doublesố loại 10000000000.6(mười tỷ phẩy sáu) là một số "thực". Sử dụng một phép cast intvào đó sẽ cho một kết quả kỳ lạ (trừ khi bạn đang ở trong checkedngữ cảnh, nhưng có thể bạn không).
Jeppe Stig Nielsen

13

Truyền sẽ bỏ qua bất kỳ thứ gì sau dấu thập phân, vì vậy 8,6 trở thành 8.

Convert.ToInt32(8.6) là cách an toàn để đảm bảo số kép của bạn được làm tròn thành số nguyên gần nhất, trong trường hợp này là 9.


1
Câu hỏi bổ sung - điều gì xảy ra nếu giá trị của double quá lớn để đẩy vào int ? Tức là nếu nó cao hơn int.MAX_VAL ?
Konrad Viltersten

1
@KonradViltersten Ném một ngoại lệ Giá trị quá lớn hoặc quá nhỏ đối với Int32.
Vamsi

11

bạn có thể làm tròn ist đôi và cast của mình:

(int)Math.Round(myDouble);

4
câu hỏi bây giờ là làm thế nào để thực hiện i1 == i2. Câu hỏi đặt ra là tại sao chúng không bằng nhau. Bị phản đối.
Adam

5

Trong ví dụ được cung cấp, số thập phân của bạn là 8,6 . Nếu nó là 8,5 hoặc 9,5, câu lệnh i1 == i2 có thể đúng. Trong thực tế, nó sẽ đúng với 8,5 và sai với 9,5.

Giải trình:

Bất kể phần thập phân là gì, câu lệnh thứ hai int i2 = (int)scoresẽ loại bỏ phần thập phân và chỉ trả lại cho bạn phần nguyên. Việc làm khá nguy hiểm vì có thể xảy ra mất dữ liệu.

Bây giờ, đối với tuyên bố đầu tiên, hai điều có thể xảy ra. Nếu phần thập phân là 5, tức là nó đã đi được một nửa, một quyết định sẽ được đưa ra. Chúng ta làm tròn lên hay xuống? Trong C #, lớp Convert thực hiện việc làm tròn của banker. Xem câu trả lời này để giải thích sâu hơn. Nói một cách đơn giản, nếu số chẵn thì làm tròn xuống, nếu số lẻ thì làm tròn lên.

Ví dụ: Hãy xem xét:

        double score = 8.5;
        int i1 = Convert.ToInt32(score); // 8
        int i2 = (int)score;             // 8

        score += 1;
        i1 = Convert.ToInt32(score);     // 10
        i2 = (int)score;                 // 9

2

ToInt32 vòng. Truyền tới int chỉ ném đi thành phần không phải là số nguyên.

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.