0Pricing
Java Academy · درس

لماذا لا نستخدم double للأموال

مشكلات دقة الفاصلة العائمة

لماذا لا نستخدم double للأموال درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

خيار افتراضي خطير

من الطبيعي أن تشعر بأن تخزين الأسعار في double هو الخيار المناسب. لكن double لا يستطيع تمثيل معظم الكسور العشرية بدقة تامة، مما يؤدي إلى أخطاء طفيفة تفسد الحسابات المالية.

المفاجأة المعتادة

عند جمع 0.1 و0.2 باستخدام double، لن تحصل على 0.3، بل على قيمة تتضمن خطأ تقريب صغيرًا.

public class Main {
    public static void main(String[] args) {
        double result = 0.1 + 0.2;
        System.out.println(result);
    }
}

سبب حدوث ذلك

تخزّن الحواسيب double بالنظام الثنائي. وكما لا يمكن كتابة الثلث بدقة تامة بالنظام العشري، لا يمكن كتابة العديد من الأعداد العشرية مثل 0.1 بدقة تامة بالنظام الثنائي.

تُخزّن أقرب قيمة تقريبية ثنائية، ويتراكم الخطأ.

تتراكم الأخطاء

قد يبدو الخطأ الصغير المفرد غير مؤثر، لكن عند تنفيذ حلقة على آلاف المعاملات، تتراكم الفروق لتتحول إلى أخطاء واضحة.

public class Main {
    public static void main(String[] args) {
        double total = 0.0;
        for (int i = 0; i < 10; i++) {
            total += 0.1;
        }
        System.out.println(total);
    }
}

فشل التساوي

بسبب أخطاء التقريب، غالبًا ما تفشل مقارنة قيم double المحسوبة باستخدام == رغم توقعك أن تكون متساوية.

public class Main {
    public static void main(String[] args) {
        double a = 0.1 + 0.2;
        double b = 0.3;
        System.out.println(a == b);
    }
}

تتطلب النقود دقة تامة

في المجال المالي، لا يُقبل الخطأ بمقدار جزء من السنت. ويتوقع المدققون أن تتطابق المجاميع حتى آخر سنت.

لذلك يجب عدم تخزين النقود مطلقًا في نوع ذي فاصلة عائمة.

الحل: BigDecimal

توفر Java الفئة BigDecimal التي تخزّن الأعداد العشرية بدقة تامة. وهي تتعقب القيمة غير المقاسة والمقياس بشكل منفصل، ولذلك تعني 0.1 فعلًا القيمة 0.1.

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("0.1");
        BigDecimal b = new BigDecimal("0.2");
        System.out.println(a.add(b));
    }
}

استخدم مُنشئ String دائمًا

أنشئ BigDecimal من String، وليس من double. إذ يؤدي تمرير قيمة double إلى نقل الخطأ الثنائي إلى BigDecimal.

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal fromDouble = new BigDecimal(0.1);
        BigDecimal fromString = new BigDecimal("0.1");
        System.out.println(fromDouble);
        System.out.println(fromString);
    }
}

أو استخدم valueOf

يمثل BigDecimal.valueOf اختصارًا آمنًا. فهو يحوّل قيمة double باستخدام تمثيلها النصي المعتمد، متجنبًا الخطأ الثنائي الخام.

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal price = BigDecimal.valueOf(19.99);
        System.out.println(price);
    }
}

تخزين النقود بالسنتات

في الحالات البسيطة، يتمثل البديل في تخزين النقود كعدد صحيح من السنتات باستخدام long. عندها تصبح 19.99 دولارًا تساوي 1999 سنتًا، وتصبح جميع العمليات الحسابية عمليات صحيحة دقيقة.

public class Main {
    public static void main(String[] args) {
        long cents = 1999;
        long total = cents * 3;
        System.out.println(total + " cents");
    }
}

الخلاصة

استخدم float وdouble في الأعمال العلمية والرسوميات، حيث تكون الأخطاء الصغيرة مقبولة. أما للنقود وأي قيمة يجب أن تكون دقيقة، فاستخدم BigDecimal أو عددًا صحيحًا من السنتات.

اختبار سريع

اختبر فهمك لدقة الأعداد ذات الفاصلة العائمة.

مراجعة

تعلّمت سبب فشل double في التعامل مع النقود:

  • لا يستطيع تمثيل الفاصلة العائمة الثنائي تخزين العديد من الأعداد العشرية بدقة تامة
  • تتراكم أخطاء مثل عدم تساوي 0.1 + 0.2 مع 0.3
  • استخدم BigDecimal لإجراء حسابات عشرية دقيقة
  • أنشئه من String أو باستخدام valueOf، وليس من قيمة double خام
  • يمثل تخزين السنتات كأعداد صحيحة خيارًا دقيقًا آخر

الأسئلة الشائعة

هل درس «لماذا لا نستخدم double للأموال» مجاني؟

نعم — نص درس «لماذا لا نستخدم double للأموال» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «لماذا لا نستخدم double للأموال»؟

مشكلات دقة الفاصلة العائمة تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «لماذا لا نستخدم double للأموال»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. لماذا لا نستخدم double للأموال
  2. العمل باستخدام BigDecimal
  3. التقريب والمقياس
  4. BigInteger للأعداد الضخمة
← العودة إلى Java Academy