الانتقال إلى المحتوى الرئيسي
أعداد موقَّعة ذات فاصلة ثابتة تحافظ على الدقة أثناء عمليات الجمع والطرح والضرب. أمّا في القسمة، فتُهمَل الخانات الأقل أهمية (من دون تقريب).

المعاملات

  • P - الدقة. النطاق الصالح: [ 1 : 76 ]. يحدّد عدد الخانات التي يمكن أن يتكوّن منها العدد (بما في ذلك الجزء الكسري). تكون الدقة افتراضيًا 10.
  • S - المقياس. النطاق الصالح: [ 0 : P ]. يحدّد عدد الخانات التي يمكن أن يتكوّن منها الجزء الكسري.
Decimal(P) مكافئ لـ Decimal(P, 0). وبالمثل، فإن الصياغة Decimal مكافئة لـ Decimal(10, 0). اعتمادًا على قيمة المعامل P، يُعد Decimal(P, S) اسمًا مرادفًا لـ:
  • P من [ 1 : 9 ] - لـ Decimal32(S)
  • P من [ 10 : 18 ] - لـ Decimal64(S)
  • P من [ 19 : 38 ] - لـ Decimal128(S)
  • P من [ 39 : 76 ] - لـ Decimal256(S)

نطاقات قيم Decimal

  • Decimal(P, S) - ( -1 * 10^(P - S), 1 * 10^(P - S) )
  • Decimal32(S) - ( -1 * 10^(9 - S), 1 * 10^(9 - S) )
  • Decimal64(S) - ( -1 * 10^(18 - S), 1 * 10^(18 - S) )
  • Decimal128(S) - ( -1 * 10^(38 - S), 1 * 10^(38 - S) )
  • Decimal256(S) - ( -1 * 10^(76 - S), 1 * 10^(76 - S) )
على سبيل المثال، يمكن لـ Decimal32(4) تمثيل أعداد من -99999.9999 إلى 99999.9999 بفاصل 0.0001.

التمثيل الداخلي

تُمثَّل البيانات داخليًا على هيئة أعداد صحيحة موقَّعة عادية بعرض البت المقابل. أما نطاقات القيم الفعلية التي يمكن تخزينها في الذاكرة فهي أكبر قليلًا مما هو محدد أعلاه، ولا يُتحقق منها إلا عند التحويل من سلسلة نصية. ولأن وحدات المعالجة المركزية الحديثة لا تدعم الأعداد الصحيحة ذات 128 بت و256 بت دعمًا أصيلًا، فإن العمليات على Decimal128 وDecimal256 تتم بالمحاكاة. لذلك يعمل Decimal128 وDecimal256 بسرعة أبطأ بكثير من Decimal32/Decimal64.

العمليات ونوع النتيجة

تؤدي العمليات الثنائية على Decimal إلى نوع نتيجة أوسع (بغضّ النظر عن ترتيب الوسائط).
  • Decimal64(S1) <op> Decimal32(S2) -> Decimal64(S)
  • Decimal128(S1) <op> Decimal32(S2) -> Decimal128(S)
  • Decimal128(S1) <op> Decimal64(S2) -> Decimal128(S)
  • Decimal256(S1) <op> Decimal<32|64|128>(S2) -> Decimal256(S)
قواعد المقياس:
  • الجمع، الطرح: S = max(S1, S2).
  • الضرب: S = S1 + S2.
  • القسمة: S = S1.
بالنسبة إلى العمليات المماثلة بين Decimal والأعداد الصحيحة، تكون النتيجة Decimal بالحجم نفسه للوسيط. العمليات بين Decimal وFloat32/Float64 غير معرّفة. إذا كنت بحاجة إليها، فيمكنك إجراء تحويل نوع صريح لأحد الوسائط باستخدام الدوال المضمنة toDecimal32 وtoDecimal64 وtoDecimal128 أو toFloat32 وtoFloat64. ضع في اعتبارك أن النتيجة ستفقد بعض الدقة، وأن تحويل النوع عملية مكلفة حسابيًا. تعيد بعض الدوال التي تعمل على Decimal النتيجة على أنها Float64 (على سبيل المثال، var أو stddev). وقد تظل الحسابات الوسيطة تُجرى باستخدام Decimal، مما قد يؤدي إلى اختلاف النتائج بين مدخلات Float64 ومدخلات Decimal التي تحمل القيم نفسها.

عمليات التحقق من تجاوز السعة

أثناء العمليات الحسابية على Decimal، قد يحدث تجاوز في سعة الأعداد الصحيحة. تُهمَل الأرقام الزائدة في الجزء الكسري (من دون تقريب). أمّا الأرقام الزائدة في الجزء الصحيح فتؤدي إلى حدوث استثناء.
لم تُطبَّق عملية التحقق من تجاوز السعة على Decimal128 وDecimal256. وفي حال حدوث تجاوز للسعة، تُعاد نتيجة غير صحيحة ولا يتم إطلاق استثناء.
SELECT toDecimal32(2, 4) AS x, x / 3
┌──────x─┬─divide(toDecimal32(2, 4), 3)─┐
│ 2.0000 │                       0.6666 │
└────────┴──────────────────────────────┘
SELECT toDecimal32(4.2, 8) AS x, x * x
DB::Exception: Scale is out of bounds.
SELECT toDecimal32(4.2, 8) AS x, 6 * x
DB::Exception: Decimal math overflow.
تؤدي فحوصات تجاوز السعة إلى إبطاء العمليات. إذا كان معروفًا أن تجاوز السعة غير وارد، فمن المنطقي تعطيل هذه الفحوصات باستخدام الإعداد decimal_check_overflow. وعند تعطيل الفحوصات ووقوع تجاوز سعة، ستكون النتيجة غير صحيحة:
SET decimal_check_overflow = 0;
SELECT toDecimal32(4.2, 8) AS x, 6 * x
┌──────────x─┬─multiply(6, toDecimal32(4.2, 8))─┐
│ 4.20000000 │                     -17.74967296 │
└────────────┴──────────────────────────────────┘
لا تقتصر فحوصات تجاوز السعة على العمليات الحسابية فحسب، بل تحدث أيضًا عند مقارنة القيم:
SELECT toDecimal32(1, 8) < 100
DB::Exception: Can't compare.
انظر أيضًا
آخر تعديل في ٢٥ يونيو ٢٠٢٦