ลองทำความเข้าใจว่าอะไรคือความแตกต่างระหว่างประเภทตัวแปรทศนิยม ทศนิยม และตัวแปรคู่ใน .NET และเมื่อใดที่ควรใช้ในกรณีการใช้งานที่ถูกต้อง และความแม่นยำของแต่ละประเภทคืออะไร
float
และ double
เป็นประเภทจุด binary แบบลอยตัว กล่าวอีกนัยหนึ่ง พวกมันแทนตัวเลขดังนี้:
10001.10010110011
ทั้งเลขฐานสองและตำแหน่งของจุดไบนารี่ถูกเข้ารหัสภายในค่า
decimal
เป็นประเภทจุดทศนิยม ทศนิยม แบบลอยตัว กล่าวอีกนัยหนึ่ง พวกมันแทนตัวเลขดังนี้:
12345.65789
ขอย้ำอีกครั้งว่า ทั้งตัวเลขและตำแหน่งของจุด ทศนิยม ได้รับการเข้ารหัสภายในค่า นั่นคือสิ่งที่ทำให้ decimal
ยังคงเป็นประเภทจุดทศนิยมแทนที่จะเป็นประเภทจุดคงที่
สิ่งสำคัญที่ควรทราบก็คือ มนุษย์คุ้นเคยกับการแสดงจำนวนที่ไม่ใช่จำนวนเต็มในรูปแบบทศนิยม และคาดหวังผลลัพธ์ที่แน่นอนในรูปแบบทศนิยม ตัวเลขทศนิยมบางตัวไม่สามารถแทนค่าจุดลอยตัวไบนารีได้ทั้งหมด เช่น 0.1 ดังนั้น หากคุณใช้ค่าจุดลอยตัวไบนารี จริงๆ แล้วคุณจะได้ค่าประมาณ 0.1 คุณจะยังคงได้รับค่าประมาณเมื่อใช้จุดทศนิยมลอยตัวเช่นกัน เช่น ผลลัพธ์ของการหาร 1 ด้วย 3 ไม่สามารถแสดงได้อย่างแม่นยำ
จะใช้อะไรเมื่อ:
- สำหรับค่าที่เป็น "ทศนิยมที่แน่นอนตามธรรมชาติ" ควรใช้
decimal
ซึ่งมักจะเหมาะสำหรับแนวคิดใดๆ ที่มนุษย์ประดิษฐ์ขึ้น คุณค่าทางการเงินเป็นตัวอย่างที่ชัดเจนที่สุด แต่ก็มีแนวคิดอื่นๆ ด้วยเช่นกัน พิจารณาคะแนนที่มอบให้กับนักดำน้ำหรือนักสเก็ตน้ำแข็ง เป็นต้น - สำหรับค่าที่เป็นสิ่งประดิษฐ์จากธรรมชาติซึ่งไม่สามารถวัดได้แน่นอนอยู่แล้ว
float
/double
จะเหมาะสมกว่า ตัวอย่างเช่น ข้อมูลทางวิทยาศาสตร์มักจะแสดงในรูปแบบนี้ ในที่นี้ ค่าดั้งเดิมจะไม่ 'แม่นยำในระดับทศนิยม' ในตอนแรก ดังนั้นจึงไม่สำคัญที่ผลลัพธ์ที่คาดหวังจะต้องรักษา 'ความแม่นยำระดับทศนิยม' ประเภทจุดไบนารี่แบบลอยตัวนั้นทำงานได้เร็วกว่าทศนิยมมาก
และยิ่งไปกว่านั้นความแม่นยำก็คือความแตกต่างหลัก
ลอย — 7 หลัก (32 บิต)
สองเท่า -15–16 หลัก (64 บิต)
ทศนิยม -28–29 หลักสำคัญ (128 บิต)
ทศนิยมมีความแม่นยำสูงกว่ามากและมักใช้ในแอปพลิเคชันทางการเงินที่ต้องการความแม่นยำในระดับสูง ทศนิยมจะช้ากว่ามาก (มากถึง 20 เท่าในการทดสอบบางอย่าง) มากกว่าทศนิยมสองเท่า/ลอย
ทศนิยมและทศนิยม/ทศนิยมไม่สามารถเปรียบเทียบได้หากไม่มีการร่าย ในขณะที่ทศนิยมและทศนิยมสามารถทำได้ ทศนิยมยังอนุญาตให้ใช้การเข้ารหัสหรือเลขศูนย์ต่อท้าย
float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);
ผลลัพธ์ :
float: 0.3333333
double: 0.333333333333333
decimal: 0.3333333333333333333333333333