Decimal مقابل Double في C#: معركة الدقة (وأعصابك)
\n\nهل سبق لك أن كتبت آلة حاسبة للراتب أو، لنقل، محاكيًا لطيران كرة، وفجأة حصلت على 0.30000000000000004 بدلاً من 0.3 المتوقعة؟ إذا كان الأمر كذلك، فمرحبًا بك في النادي. سؤال "decimal vs double! - Which one should I use and when?" هو أحد أكثر الأسئلة شيوعًا على Stack Overflow، وليس من دون سبب. يبدو الأمر وكأنه مجرد اختيار بين نوعين من الأرقام ذات الفاصلة العائمة. لكنه في الواقع اختيار بين كارثة مالية ودقة علمية (أو العكس).
في هذه المقالة، سنحسم هذا الجدل الأبدي مرة واحدة وإلى الأبد. ستتعرف على الفرق بين نوع decimal في C# و نوع double، وأين يستخدم كل منهما، والأهم من ذلك، كيف لا ترتكب أخطاء في عام 2025. هيا بنا!
\n\nباختصار عن الأساسيات: ما الذي يحدث تحت الغطاء؟
\n\nقبل أن نبدأ في تبادل الحجج، دعنا نلقي نظرة على المواصفات. لكل نوع بنيته الخاصة، وهي التي تحدد أين سيكون ملكًا وأين سيكون منبوذًا.
\n\nDouble (المعروف أيضًا باسم System.Double)
\n- \n
- الحجم: 64 بت (8 بايت). \n
- الدقة: حوالي 15-17 رقمًا معنويًا. \n
- النطاق: ضخم (من ±5.0 × 10−324 إلى ±1.7 × 10308). \n
- التمثيل: فاصلة عائمة وفقًا لمعيار IEEE 754 (ثنائي). \n
- الأداء: عالي. المعالجات محسّنة للعمل مع double. \n
Decimal (المعروف أيضًا باسم System.Decimal)
\n- \n
- الحجم: 128 بت (16 بايت). \n
- الدقة: 28-29 رقمًا معنويًا. \n
- النطاق: أصغر (من ±1.0 × 10−28 إلى ±7.9 × 1028). \n
- التمثيل: عشري (في الأساس، عدد صحيح مع إزاحة الفاصلة). \n
- الأداء: أقل. لا يوجد دعم أجهزة على وحدة المعالجة المركزية، جميع الحسابات برمجية. \n
الفرق الرئيسي الذي يجب تذكره: double هو كسر ثنائي، بينما decimal هو كسر عشري. ولهذا السبب تنشأ "أخطاء التقريب" الشهيرة.
\n\nلماذا "يكسر" double المال، لكنه مثالي للعلوم؟
\n\nتخيل أنك تحاول كتابة الرقم 0.1 في النظام الثنائي. سيكون كسرًا دوريًا لا نهائيًا: 0.0001100110011.... يقطعه الكمبيوتر، وينتج عن ذلك خطأ صغير ولكنه حاسم. بالنسبة للحسابات العلمية (محاكاة الطقس، الفيزياء، الرسومات)، يتراكم هذا الخطأ ولكنه ضمن الحدود المسموح بها. بالنسبة للمالية، هذا يعني "سرقة" فلس واحد من مليون مستخدم.
أما Decimal فيخزن الرقم كعدد صحيح (على سبيل المثال، 1/10 = 0.1 يُخزن كعدد صحيح 1 ومعلومات بأن الفاصلة يجب أن تُزاح بمقدار خانة واحدة). لذلك، دقة decimal مثالية للكسور العشرية.
\n\nمتى تستخدم decimal في C#؟ (تنبيه: للمال)
\n\nالقاعدة الذهبية التي ستنقذ مشروعك: استخدم decimal للحسابات المالية والنقدية والمحاسبية. إذا كان متغيرك يحتوي على روبل أو دولارات أو نسب فائدة أو ضريبة القيمة المضافة، فاختيارك واضح.
\n\nإليك مثال لماذا يعتبر double شرًا للمحفظة:
\n\nusing System;\n\npublic class MoneyExample\n{\n public static void Main()\n {\n // مثال سيء باستخدام double\n double price = 10.99;\n double tax = 0.07;\n double totalDouble = price + (price * tax);\n Console.WriteLine($"Double total: {totalDouble}"); // قد ينتج 11.759300000000001\n\n // مثال جيد باستخدام decimal\n decimal priceDec = 10.99m;\n decimal taxDec = 0.07m;\n decimal totalDec = priceDec + (priceDec * taxDec);\n Console.WriteLine($"Decimal total: {totalDec}"); // بالضبط: 11.7593\n }\n}\n\nهل ترى هذه "الزيادة