ฉันจะแปลงทศนิยมให้เป็น int ได้อย่างไร
ฉันจะแปลงทศนิยมให้เป็น int ได้อย่างไร
คำตอบ:
ใช้Convert.ToInt32
จากmscorlib
ใน
decimal value = 3.14m;
int n = Convert.ToInt32(value);
ดูMSDN Decimal.ToInt32
นอกจากนี้คุณยังสามารถใช้ อีกครั้งดูMSDN ในที่สุดคุณสามารถทำการส่งโดยตรงเช่นเดียวกับใน
decimal value = 3.14m;
int n = (int) value;
null
เทียบ0
กับกับ""
) ผมอยากแนะนำให้ไม่เคยใช้แปลงถ้าคุณอย่างต้องมีความยืดหยุ่น (เช่นในสถานการณ์พิมพ์แบบไดนามิก)
OverflowException
และผลใน ฉันเชื่อว่า @Will จะให้คำตอบที่ดีกว่าที่นี่stackoverflow.com/a/501165/39532
Convert.ToInt32
และDecimal.ToInt32
ประพฤติแตกต่างกัน จาก MSDN: Decimal.ToInt32
- ค่าส่งคืนเป็นส่วนหนึ่งของค่าทศนิยม ตัวเลขที่เป็นเศษจะถูกตัดทอน Convert.ToInt32
- ส่งคืนค่าที่ปัดเศษเป็นจำนวนเต็มแบบ 32 บิตที่ใกล้ที่สุด หากค่าอยู่ครึ่งทางระหว่างสองจำนวนเต็มจำนวนคู่จะถูกส่งคืน นั่นคือ 4.5 ถูกแปลงเป็น 4 และ 5.5 ถูกแปลงเป็น 6
คุณทำไม่ได้
แน่นอนว่าคุณสามารถทำได้อย่างไรก็ตาม int (System.Int32) ไม่ใหญ่พอที่จะเก็บค่าทศนิยมทุกค่าที่เป็นไปได้
นั่นหมายความว่าถ้าคุณใช้ทศนิยมที่มีขนาดใหญ่กว่า int.MaxValue คุณจะล้นและถ้าทศนิยมมีขนาดเล็กกว่า int.MinValue ก็จะไหลล้น
จะเกิดอะไรขึ้นเมื่อคุณอยู่ภายใต้ / ล้น หนึ่งในสองสิ่ง หากบิลด์ของคุณไม่ถูกตรวจสอบ (เช่น CLR ไม่สนใจว่าคุณทำ) แอปพลิเคชันของคุณจะดำเนินการต่อหลังจากค่าเกิน / ต่ำกว่า แต่ค่าใน int จะไม่เป็นอย่างที่คุณคาดไว้ สิ่งนี้สามารถนำไปสู่ข้อบกพร่องเป็นระยะ ๆ และอาจแก้ไขได้ยาก คุณจะสิ้นสุดการสมัครของคุณในสถานะที่ไม่รู้จักซึ่งอาจส่งผลให้แอปพลิเคชันของคุณทำลายข้อมูลสำคัญใด ๆ ที่แอปพลิเคชันทำงาน ไม่ดี.
หากแอสเซมบลีของคุณถูกตรวจสอบ (คุณสมบัติ -> build-> ขั้นสูง -> ตรวจสอบการคำนวณทางคณิตศาสตร์มากเกินไป / อันเดอร์โฟลหรือตัวเลือก / ตรวจสอบคอมไพเลอร์) รหัสของคุณจะโยนข้อยกเว้นเมื่อเกิดภายใต้ / ล้น นี่อาจจะดีกว่าไม่ได้; อย่างไรก็ตามค่าเริ่มต้นสำหรับแอสเซมบลีไม่ได้ตรวจสอบเกิน / underflow
คำถามจริงคือ "คุณพยายามทำอะไร" ไม่มีใครสามารถบอกคุณได้ว่าคุณควรทำอะไรในกรณีนี้นอกเหนือจากที่ชัดเจน: ไม่ต้องทำ
หากคุณไม่สนใจเป็นพิเศษคำตอบที่นี่จะใช้ได้ อย่างไรก็ตามคุณควรสื่อสารความเข้าใจของคุณว่าอาจเกิดโอเวอร์โฟลว์และมันไม่สำคัญโดยการห่อโค้ดคาสต์ของคุณในบล็อกที่ไม่ได้ตรวจสอบ
unchecked
{
// do your conversions that may underflow/overflow here
}
ด้วยวิธีการที่ผู้คนที่อยู่ข้างหลังคุณเข้าใจว่าคุณไม่สนใจและถ้าในอนาคตมีคนเปลี่ยนงานสร้างของคุณเป็น / ตรวจสอบรหัสของคุณจะไม่ผิดพลาดโดยไม่คาดคิด
หากสิ่งที่คุณต้องการทำคือปล่อยส่วนที่เป็นเศษส่วนของจำนวนออกจากส่วนที่เป็นส่วนประกอบคุณสามารถใช้ Math.Truncate
decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));
int i = (int)d;
จะทำให้คุณปัดเศษตัวเลขลง
หากคุณต้องการปัดเศษให้เป็นเลขคู่ที่ใกล้ที่สุด (เช่น> .5 จะปัดเศษขึ้น) คุณสามารถใช้
int i = (int)Math.Round(d, MidpointRounding.ToEven);
โดยทั่วไปคุณสามารถแปลงระหว่างประเภทตัวเลขทั้งหมดใน C # หากไม่มีข้อมูลที่จะหายไประหว่างการส่งนักแสดงคุณสามารถทำได้โดยปริยาย:
int i = 10;
decimal d = i;
แม้ว่าคุณจะสามารถทำได้อย่างชัดเจนหากคุณต้องการ:
int i = 10;
decimal d = (decimal)i;
อย่างไรก็ตามหากคุณกำลังจะสูญเสียข้อมูลผ่านการส่งนักแสดงคุณต้องทำอย่างชัดเจน (เพื่อแสดงให้คุณทราบว่าคุณอาจกำลังสูญเสียข้อมูล):
decimal d = 10.5M;
int i = (int)d;
ที่นี่คุณกำลังสูญเสีย ".5" สิ่งนี้อาจใช้ได้ แต่คุณต้องมีความชัดเจนเกี่ยวกับเรื่องนี้และทำการบล็อกที่ชัดเจนเพื่อแสดงให้คุณรู้ว่าคุณอาจสูญเสียข้อมูล
ToEven
ควรป้องกันการดริฟท์สถิติ หากคุณทำงานกับรายการหรือเงินที่คิดค่าบริการAwayFromZero
ดูเหมือนว่าเป็นตัวเลือกที่เหมาะสม
decimal vIn = 0.0M;
int vOut = Convert.ToInt32(vIn);
นี่คือหน้าเว็บประเภทแปลงข้อมูลที่มีประโยชน์มากสำหรับผู้อื่น http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
System.Decimal
ใช้IConvertable
อินเตอร์เฟสซึ่งมีToInt32()
สมาชิก
การโทรSystem.Decimal.ToInt32()
หาคุณหรือไม่
เคล็ดลับที่เป็นระเบียบสำหรับการปัดเศษอย่างรวดเร็วคือการเพิ่ม 0.5 ก่อนที่คุณจะแปลงทศนิยมเป็น int
decimal d = 10.1m;
d += .5m;
int i = (int)d;
ยังคงออกจากi=10
แต่
decimal d = 10.5m;
d += .5m;
int i = (int)d;
i=11
จะปัดเศษขึ้นเพื่อให้
ฉันชอบใช้Math.Round , Math.Floor , Math.CeilingหรือMath.Truncateเพื่อกำหนดโหมดการปัดเศษอย่างเหมาะสมตามความเหมาะสม
โปรดทราบว่าพวกเขาทั้งหมดกลับทศนิยมเช่นกัน - เนื่องจากทศนิยมมีช่วงที่มีค่ามากกว่า Int32 ดังนั้นคุณจะยังคงต้องส่ง (และตรวจสอบล้น / อันเดอร์โฟล์)
checked {
int i = (int)Math.Floor(d);
}
การปัดเศษทศนิยมเป็นจำนวนเต็มที่ใกล้ที่สุด
decimal a ;
int b = (int)(a + 0.5m);
เมื่อa = 49.9
แล้วb = 50
เมื่อa = 49.5
แล้วb = 50
เมื่อa = 49.4
แล้วb = 49
ฯลฯ
ฉันพบว่าตัวดำเนินการแคสต์ไม่ทำงานหากคุณมีทศนิยมแบบกล่อง (เช่นค่าทศนิยมภายในประเภทวัตถุ) Convert.ToInt32 (ทศนิยมเป็นวัตถุ) ทำงานได้ดีในกรณีนี้
สถานการณ์นี้เกิดขึ้นเมื่อดึงค่า IDENTITY / AUTONUMBER จากฐานข้อมูล:
SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar()); // works
int ID = (int)foo.ExecuteScalar(); // throws InvalidCastException
SELECT SCOPE_IDENTITY()
ส่งกลับnumeric(38, 0)
ซึ่งแปลdecimal
โดย. NET foo.ExecuteScalar()
ส่งกลับdecimal
ชนิดบรรจุกล่องเป็นที่ไม่สามารถออกเสียงโดยตรงกับobject
หรือจะทำงาน int
(int)(decimal)foo.ExecuteScalar()
Convert.ToInt32(foo.ExecuteScalar())
ดูเหมือนว่าไม่มีคำตอบที่จะจัดการกับ OverflowException / UnderflowException ที่มาจากการพยายามแปลงทศนิยมที่อยู่นอกช่วงของ int
int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));
วิธีนี้จะคืนค่า int สูงสุดหรือต่ำสุดที่เป็นไปได้ถ้าค่าทศนิยมอยู่นอกช่วง int คุณอาจต้องการเพิ่มการปัดเศษด้วย Math.Round, Math.Ceiling หรือ Math.Floor เมื่อค่านั้นอยู่ในช่วง int