ลองทำความเข้าใจว่าอะไรคือความแตกต่างระหว่างประเภทตัวแปรทศนิยม ทศนิยม และตัวแปรคู่ใน .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