การแปลงคู่เป็น int ใน C #


108

ในรหัสของเราเรามีสองเท่าที่เราต้องแปลงเป็น int

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

ใครช่วยอธิบายทีว่าทำไมi1 != i2?

ผลลัพธ์ที่ได้คือ: i1 = 9และi2 = 8.


5
Math.Truncate(score)เป็นการแสดงเจตนาอย่างชัดเจนมากกว่า(int)score
Lu55

4
แต่ Math.Truncate ส่งกลับค่าสองเท่าหรือทศนิยมไม่ใช่ int
Sergioet

คำตอบ:


172

เพราะConvert.ToInt32รอบ:

Return Value: ปัดเศษเป็นจำนวนเต็ม 32 บิตที่ใกล้เคียงที่สุด ถ้าค่าอยู่กึ่งกลางระหว่างจำนวนเต็มสองจำนวนจะส่งคืนเลขคู่ นั่นคือ 4.5 ถูกแปลงเป็น 4 และ 5.5 ถูกแปลงเป็น 6

... ในขณะที่นักแสดงตัดทอน :

เมื่อคุณแปลงจากค่าสองเท่าหรือค่าลอยเป็นชนิดปริพันธ์ค่าจะถูกตัดทอน

อัปเดต:ดูความคิดเห็นของ Jeppe Stig Nielsen ด้านล่างสำหรับความแตกต่างเพิ่มเติม (ซึ่งจะไม่เกิดขึ้นหากscoreเป็นจำนวนจริงตามที่เห็นในกรณีนี้)


6
ลิงค์ของคุณอธิบายได้ดีที่สุดและไม่ง่ายเหมือน round vs truncate: Type: System.Int32 ปัดเศษเป็นจำนวนเต็ม 32 บิตที่ใกล้เคียงที่สุด ถ้าค่าอยู่กึ่งกลางระหว่างจำนวนเต็มสองจำนวนจะส่งคืนเลขคู่ นั่นคือ 4.5 ถูกแปลงเป็น 4 และ 5.5 ถูกแปลงเป็น 6
ericosg

@ericosg: ใช่ว่าจะปกปิดความแตกต่างถ้าscoreเป็นแทน8.5 8.6ฉันอัปเดตคำตอบเพื่อรวมคำพูด ขอบคุณสำหรับข้อมูล
จอน

6
และถ้าscoreเป็นNaNหรืออินฟินิตี้ จำกัด หรือ แต่อยู่นอกช่วงของInt32แล้วConvert.ToInt32จะโยนข้อยกเว้น นักแสดงจะส่งคืนintแต่คุณจะรู้ว่าอันไหน (ในการนำไปใช้งานของฉันInt32.MinValue) เพราะคุณอยู่ในuncheckedบริบท (หากคุณอยู่ในcheckedบริบทนักแสดงจะมีข้อยกเว้นเช่นกันในกรณีเหล่านี้)
Jeppe Stig Nielsen

@JeppeStigNielsen: ขอบคุณสำหรับข้อมูลฉันอัปเดตคำตอบเพื่อพูดถึงเรื่องนี้ด้วย
จอน

ดี. แต่ฉันคิดว่าDoubleหมายเลขประเภท10000000000.6(หมื่นล้านจุดหก) เป็นตัวเลข "จริง" การใช้การแคสต์เพื่อintให้ได้ผลลัพธ์ที่แปลก (เว้นแต่คุณจะอยู่ในcheckedบริบท แต่คุณอาจไม่ได้ทำ)
Jeppe Stig Nielsen

15

การแคสต์จะไม่สนใจอะไรเลยหลังจุดทศนิยมดังนั้น 8.6 จึงกลายเป็น 8

Convert.ToInt32(8.6) เป็นวิธีที่ปลอดภัยเพื่อให้แน่ใจว่าคู่ของคุณถูกปัดเศษเป็นจำนวนเต็มที่ใกล้เคียงที่สุดในกรณีนี้คือ 9


1
คำถามโบนัส - จะเกิดอะไรขึ้นถ้าค่าของคู่ใหญ่เกินกว่าที่จะผลักเข้าไปในint ? เช่นถ้าสูงกว่าint.MAX_VAL ?
Konrad Viltersten

1
@KonradViltersten โยนข้อยกเว้นค่าใหญ่เกินไปหรือเล็กเกินไปสำหรับ Int32
Vamsi

11

คุณสามารถปัดเศษคู่ของคุณและโยน ist:

(int)Math.Round(myDouble);

4
คำถามคือตอนนี้วิธีการi1 == i2ที่จะทำให้ คำถามคือว่าทำไมถึงไม่เท่ากัน โหวตลดลง
อดัม

6

ในตัวอย่างให้ทศนิยมของคุณคือ8.6 หากเป็น 8.5 หรือ 9.5 คำสั่งi1 == i2 อาจเป็นจริง Infact มันน่าจะเป็นจริงสำหรับ 8.5 และเท็จสำหรับ 9.5

คำอธิบาย:

โดยไม่คำนึงถึงส่วนทศนิยมคำสั่งที่สองint i2 = (int)scoreจะทิ้งส่วนทศนิยมและส่งคืนส่วนจำนวนเต็มให้คุณ สิ่งที่ค่อนข้างอันตรายที่ต้องทำเนื่องจากข้อมูลอาจสูญหายได้

ตอนนี้สำหรับคำสั่งแรกสองสิ่งสามารถเกิดขึ้นได้ ถ้าส่วนทศนิยมเป็น 5 นั่นคือมันผ่านไปครึ่งทางจะต้องทำการตัดสินใจ เราปัดขึ้นหรือลง? ใน C # คลาส Convert จะใช้การปัดเศษของนายธนาคาร ดูคำตอบนี้สำหรับคำอธิบายที่ลึกซึ้งยิ่งขึ้น ใส่เพียงแค่ถ้าตัวเลขเป็นเลขคู่ให้ปัดเศษลงหากตัวเลขเป็นเลขคี่ให้ปัดเศษขึ้น

เช่นพิจารณา:

        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 รอบ. การแคสต์ไปที่ int เพียงแค่โยนส่วนประกอบที่ไม่ใช่จำนวนเต็มออกไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.