الفرق بين المراجعتين ل"Python/decimal"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
ط
 
(7 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة)
سطر 1: سطر 1:
 
<noinclude>{{DISPLAYTITLE:الأعداد العشرية decimal في بايثون}}</noinclude>
 
<noinclude>{{DISPLAYTITLE:الأعداد العشرية decimal في بايثون}}</noinclude>
 
+
تتيح وحدة <code>decimal</code> إجراء حسابات سريعة على الأعداد العشرية مع ضمان التقريب الصحيح.<syntaxhighlight lang="python3">
تتيح [[الوحدات في بايثون|وحدة]] <code>decimal</code> إجراء حسابات سريعة على الأعداد العشرية مع ضمان التقريب الصحيح.<syntaxhighlight lang="python3">
 
 
>>> import decimal
 
>>> import decimal
 
 
>>> Decimal(10)
 
>>> Decimal(10)
 
 
Decimal('10')
 
Decimal('10')
 
 
>>> Decimal('3.14')
 
>>> Decimal('3.14')
 
 
Decimal('3.14')
 
Decimal('3.14')
 
 
>>> Decimal(3.14)
 
>>> Decimal(3.14)
 
 
Decimal('3.140000000000000124344978758017532527446746826171875')
 
Decimal('3.140000000000000124344978758017532527446746826171875')
 +
</syntaxhighlight>
  
</syntaxhighlight>تتفوق هذه [[الوحدات في بايثون|الوحدة]] على نوع الأعداد العشرية float بعدة ميزات:
+
== ميزات الوحدة decimal ==
* العدد العشري decimal "يستند إلى نموذج أعداد عشرية ذات فاصلة عائمة يراعي الاستخدام البشري ويلتزم بمبدأ أساسي هو أنّه يجب أن توفّر الحواسيب عمليات حسابية تعمل بنفس الطريقة التي يتعلّمها الناس في المدارس" - حسب مواصفات العمليات الحسابية التي تجرى على الأعداد العشرية decimal.
+
تتفوق هذه [[Python/modules|الوحدة]] على نوع [[Python/float|الأعداد العشرية float]] بعدة ميزات:
 +
* العدد العشري decimal "يستند إلى نموذج أعداد عشرية ذات فاصلة عائمة يراعي الاستخدام البشري ويلتزم بمبدأ أساسي هو أنّه يجب أن توفّر الحواسيب عمليات حسابية تعمل بنفس الطريقة التي يتعلّمها الناس في المدارس" - اقتباسٌ من مواصفات العمليات الحسابية التي تجرى على الأعداد العشرية decimal.
  
* يمكن تمثيل الأعداد العشرية decimal بدقّة، أما الأرقام مثل <code>1.1</code> و <code>2.2</code> فلا تمثل تمثيلًا دقيقًا في النظام الثنائي [[الأعداد العشرية (ذات الفاصلة العائمة) float في بايثون|للأعداد ذات الفاصلة العائمة]]. ولا يتوقع المستخدم أن تعطي العملية الحسابية ‎<code>1.1 + 2.2‎</code> النتيجة <code>3.3000000000000003</code> كما هو الحال مع الأعداد في النظام الثنائي للأعداد ذات الفاصلة العائمة.
+
* يمكن تمثيل الأعداد العشرية decimal بدقّة، أما الأرقام مثل <code>1.1</code> و <code>2.2</code> فلا تمثل تمثيلًا دقيقًا في النظام الثنائي [[Python/float|للأعداد ذات الفاصلة العائمة]]. ولا يتوقع المستخدم أن تعطي العملية الحسابية ‎<code>1.1 + 2.2‎</code> النتيجة <code>3.3000000000000003</code> كما هو الحال مع الأعداد في النظام الثنائي للأعداد ذات الفاصلة العائمة.
  
* تحافظ الأعداد العشرية decimal على الدقة عند إجراء العمليات الحسابية، ففي هذا النظام يكون ناتج العمليات التالية: <code>‎0.1 + 0.1 + 0.1 - 0.3</code> هو الصفر، أما في النظام الثنائي للفاصلة العائمة يكون الناتج <code>5.5511151231257827e-017</code>. صحيح أن هذا الرقم قريب جدًّا من الصفر، ولكن تعيق هذه الفروقات إجراء عمليات مقارنة دقيقة للمساواة إلى جانب أنّ هذه الفروقات يمكن أن تتزايد مع الاستمرار في إجراء العمليات الحسابية؛ لذا يفضل استخدام النوع decimal في التطبيقات المحاسبية التي تتطلّب إجراء مقارنات مساواة صارمة.
+
* تحافظ الأعداد العشرية decimal على الدقة عند إجراء العمليات الحسابية، ففي هذا النظام يكون ناتج العمليات التالية: <code>‎0.1 + 0.1 + 0.1 - 0.3</code> هو الصفر، أما في النظام الثنائي [[Python/float|للفاصلة العائمة]] يكون الناتج <code>5.5511151231257827e-017</code>. صحيح أن هذا الرقم قريب جدًّا من الصفر، ولكن تعيق هذه الفروقات إجراء عمليات مقارنة دقيقة للمساواة إلى جانب أنّ هذه الفروقات يمكن أن تتزايد مع الاستمرار في إجراء العمليات الحسابية؛ لذا يفضل استخدام النوع decimal في التطبيقات المحاسبية التي تتطلّب إجراء مقارنات مساواة صارمة.
  
* تعتمد [[الوحدات في بايثون|وحدة]] decimal مفهوم الأعداد المعنوية significant؛ لذا فإنّ ناتج العملية ‎<code>1.30 + 1.20</code> هو <code>2.50</code>، حيث تحتفظ اللغة بالصفر الأخير إشارة إلى أنّه عدد معنوي. مفهوم الأعداد المعنوية هو من المفاهيم الشائعة لتمثيل الأرقام في التطبيقات المالية والمحاسبية. وفي عملية الضرب تستخدم جميع الأرقام للحصول على الناتج، فعلى سبيل المثال تعطي العملية <code>‎1.3 * 1.2</code> الناتج <code>1.56</code> أما العملية <code>‎1.30 * 1.20</code> فتعطي الناتج <code>1.5600</code>.
+
* تعتمد [[Python/modules|وحدة]] decimal مفهوم الأعداد المعنوية (significant places)؛ لذا فإنّ ناتج العملية ‎<code>1.30 + 1.20</code> هو <code>2.50</code>، إذ تحتفظ اللغة بالصفر الأخير إشارة إلى أنّه عدد معنوي. مفهوم الأعداد المعنوية هو من المفاهيم الشائعة لتمثيل الأرقام في التطبيقات المالية والمحاسبية. وفي عملية الضرب تستخدم جميع الأرقام للحصول على الناتج، فعلى سبيل المثال تعطي العملية <code>‎1.3 * 1.2</code> الناتج <code>1.56</code> أما العملية <code>‎1.30 * 1.20</code> فتعطي الناتج <code>1.5600</code>.
  
* على عكس [[الأعداد العشرية (ذات الفاصلة العائمة) float في بايثون|الأعداد العشرية ذات الفاصلة العائمة]]، يمكن تحديد مقدار الدقة المعتمدة في الأعداد العشرية decimal من قبل المستخدم (القيمة الافتراضية هي 28 مرتبة) ويمكن استخدام أي عدد مهما كان كبيرًا، مثال:
+
* على عكس [[Python/float|الأعداد العشرية ذات الفاصلة العائمة]]، يمكن تحديد مقدار الدقة المعتمدة في الأعداد العشرية decimal من قبل المستخدم (القيمة الافتراضية هي 28 مرتبة) ويمكن استخدام أي عدد مهما كان كبيرًا، مثال:
 
<syntaxhighlight lang="python3">
 
<syntaxhighlight lang="python3">
 
>>> from decimal import *
 
>>> from decimal import *
 
 
>>> getcontext().prec = 6
 
>>> getcontext().prec = 6
 
 
>>> Decimal(1) / Decimal(7)
 
>>> Decimal(1) / Decimal(7)
 
 
Decimal('0.142857')
 
Decimal('0.142857')
 
 
>>> getcontext().prec = 28
 
>>> getcontext().prec = 28
 
 
>>> Decimal(1) / Decimal(7)
 
>>> Decimal(1) / Decimal(7)
 
 
Decimal('0.1428571428571428571428571429')
 
Decimal('0.1428571428571428571428571429')
 
</syntaxhighlight>
 
</syntaxhighlight>
* تستخدم الأعداد العشرية بنوعيها float و decimal في بايثون بالاعتماد على المعايير المعروفة، ويعرض النوع float جزءًا بسيطًا من هذه المعايير، في حين أنّ [[الوحدات في بايثون|وحدة]] decimal تعرض جميع الأجزاء المطلوبة ضمن هذه المعايير. ويمكن للمبرمج - عند الحاجة - أن يسيطر بصورة تامة على عمليات التقريب والتعامل مع الإشارات signals، ويمكن كذلك فرض عمليات حسابية دقيقة ومضبوطة باستخدام استثناءات توقف تنفيذ أي عملية حسابية غير دقيقة.
+
* تستخدم الأعداد العشرية بنوعيها [[Python/float|float]] و decimal في بايثون بالاعتماد على المعايير المعروفة، ويعرض النوع [[Python/float|float]] جزءًا بسيطًا من هذه المعايير، في حين أنّ وحدة decimal تعرض جميع الأجزاء المطلوبة ضمن هذه المعايير. ويمكن للمبرمج - عند الحاجة - أن يسيطر بصورة تامة على عمليات التقريب والتعامل مع الإشارات signals، ويمكن كذلك فرض عمليات حسابية دقيقة ومضبوطة باستخدام استثناءات توقف تنفيذ أي عملية حسابية غير دقيقة.
  
* صمّمت [[الوحدات في بايثون|وحدة]] decimal لتدعم كلًّا من العمليات الحسابية على الأرقام العشرية غير المقرّبة الدقيقة (تسمى في بعض الأحيان العمليات الحسابية على الأعداد ذات الفاصلة الثابتة fixed-point arithmetics) والعمليات الحسابية على الأعداد ذات الفاصلة العائمة المقرّبة.
+
* صمّمت وحدة decimal لتدعم كلًّا من العمليات الحسابية على الأرقام العشرية غير المقرّبة الدقيقة (تسمى في بعض الأحيان العمليات الحسابية على الأعداد ذات الفاصلة الثابتة [fixed-point arithmetics]) والعمليات الحسابية على الأعداد ذات الفاصلة العائمة المقرّبة.
يتمحور تصميم [[الوحدات في بايثون|وحدة]] decimal على ثلاثة مفاهيم أساسية: العدد العشري، السياق context الخاص بالعملية الحسابية، والإشارة signal.
+
يتمحور تصميم وحدة decimal على ثلاثة مفاهيم أساسية: العدد العشري، والسياق (context) الخاص بالعملية الحسابية، والإشارة (signal).
  
العدد العشري غير قابل للتغيير immutable، ويمتلك إشارة، وأعداد coefficient وأسًّا. وللحفاظ على الأعداد الاعتبارية لا تحذف اللغة الأصفار الأخيرة في الرقم. تضمّ الأعداد العشرية decimals كذلك قيمًا خاصّة مثل <code>Infinity</code>، و <code>‎-Infinity</code> و <code>NaN</code>، وتميّز أيضًا بين القيمتين <code>‎-0</code> و <code>‎+0</code>.
+
العدد العشري غير قابل للتغيير (immutable)، ويمتلك إشارةً وأعداد coefficient وأسًّا. وللحفاظ على الأعداد المعنوية لا تحذف اللغة الأصفار الأخيرة في الرقم. تضمّ الأعداد العشرية decimals كذلك قيمًا خاصّة مثل <code>Infinity</code>، و <code>‎-Infinity</code> و <code>NaN</code>، وتميّز أيضًا بين القيمتين <code>‎-0</code> و <code>‎+0</code>.
  
يمثّل سياق العمليات الحسابية بيئة تحدّد الدقة، وقواعد التقريب، وحدود الأسس exponents، ورايات flags تحدّد نتائج العمليات، ومفعّلات المصائد trap enablers تحدّد ما إذا كانت الإشارة تعامل معاملة [[الاستثناءات في بايثون|الاستثناءات exceptions]]. تقدّم اللغة خيارات التقريب التالية: <code>‎ROUND_CEILING، ROUND_DOWN، ROUND_FLOOR، ROUND_HALF_DOWN، ROUND_HALF_EVEN، ROUND_HALF_UP، ROUND_UP، ROUND_05UP‎.</code>
+
يمثّل سياق العمليات الحسابية بيئة تحدّد الدقة، وقواعد التقريب، وحدود الأسس (exponents)، ورايات (flags) تحدّد نتائج العمليات، ومفعّلات المصائد (trap enablers) تحدّد ما إذا كانت الإشارة تعامل معاملة [[Python/exceptions|الاستثناءات]] (exceptions). تقدّم اللغة خيارات التقريب التالية: <code>ROUND_CEILING</code> و <code>ROUND_DOWN</code> و <code>ROUND_FLOOR</code> و <code>ROUND_HALF_DOWN</code> و <code>ROUND_HALF_EVEN</code> و <code>ROUND_HALF_UP</code> و <code>ROUND_UP</code> و <code>ROUND_05UP</code>.
  
الإشارات هي مجموعة من الشروط الاستثنائية التي تظهر أثناء إجراء العمليات الحسابية. ويمكن تجاهل هذه الإشارات، أو عدّها مصدرًا للمعلومات، أو معاملتها [[الاستثناءات في بايثون|كاستثناءات]] وذلك حسب الحاجة. تقدّم اللغة الإشارات التالية في [[الوحدات في بايثون|وحدة]] decimal:
+
الإشارات هي مجموعة من الشروط الاستثنائية التي تظهر أثناء إجراء العمليات الحسابية. ويمكن تجاهل هذه الإشارات، أو عدّها مصدرًا للمعلومات، أو معاملتها [[Python/exceptions|كاستثناءات]] وذلك حسب الحاجة. تقدّم اللغة الإشارات التالية في وحدة decimal: <code>Underflow</code> و <code>Overflow</code> و <code>Subnormal</code> و <code>Rounded</code> و <code>Inexact</code> و <code>DivisionByZero</code> و <code>InvalidOperation</code> و <code>Clamped</code> و <code>FloatOperation</code>.
 
 
<code>Underflow</code> و <code>Overflow</code> و <code>Subnormal</code> و <code>Rounded</code> و <code>Inexact</code> و <code>DivisionByZero</code> و <code>InvalidOperation</code> و <code>Clamped</code> و <code>FloatOperation</code>.
 
  
 
لكل راية هناك trap enabler، وعندما ظهور إشارة يتم تعيين القيمة <code>1</code> للراية الخاصة بها، وبعد ذلك إن تم تعيين القيمة <code>1</code> لـ trap enabler تطلق اللغة استثناءً. تبقى قيمة الرايات ثابتة ويجب على المستخدم إعادة تعيين قيمتها قبل مراقبة الحسابات مرة أخرى.
 
لكل راية هناك trap enabler، وعندما ظهور إشارة يتم تعيين القيمة <code>1</code> للراية الخاصة بها، وبعد ذلك إن تم تعيين القيمة <code>1</code> لـ trap enabler تطلق اللغة استثناءً. تبقى قيمة الرايات ثابتة ويجب على المستخدم إعادة تعيين قيمتها قبل مراقبة الحسابات مرة أخرى.
  
راجع أيضًا: مواصفات IBM العامة للعمليات الحسابية على الأعداد العشرية، [http://speleotrove.com/decimal/decarith.html والمواصفات العامة للعمليات الحسابية على الأعداد العشرية.]
+
راجع أيضًا: مواصفات IBM العامة للعمليات الحسابية على الأعداد العشرية، [http://speleotrove.com/decimal/decarith.html المواصفة العامة للعمليات الحسابية على الأعداد العشرية].
  
= استخدام [[الوحدات في بايثون|وحدة]] decimal =
+
= استخدام وحدة decimal =
لاستخدام [[وحدة]] decimal يجب في البداية استيرادها، واستعراض السياق الحالي باستخدام [[الدوال في بايثون|الدالة]] <code>getcontext()</code>‎ وتعيين قيم جديدة لمقدار الدقة والتقريب والمصائد المفعّلة enabled traps، مثال:<syntaxhighlight lang="python3">
+
لاستخدام وحدة decimal يجب في البداية استيرادها، واستعراض السياق الحالي باستخدام الدالة <code>getcontext()</code>‎ وتعيين قيم جديدة لمقدار الدقة والتقريب والمصائد المفعّلة (enabled traps)، مثال:<syntaxhighlight lang="python3">
 
>>> from decimal import *
 
>>> from decimal import *
 
 
>>> getcontext()
 
>>> getcontext()
 
 
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
 
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
 
 
capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
 
capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
 
 
InvalidOperation])
 
InvalidOperation])
 
 
>>> getcontext().prec = 7 # تعيين مقدار جديد للدقة
 
>>> getcontext().prec = 7 # تعيين مقدار جديد للدقة
</syntaxhighlight>يمكن بناء نسخ [[الكائنات في بايثون|الكائن]] decimal من [[الأعداد الصحيحة في بايثون|الأعداد الصحيحة]]، أو [[السلاسل النصية في بايثون|السلاسل النصية]]، أو [[الأعداد العشرية floats]] أو [[الصفوف tuples في بايثون|الصفوف tuples]]. عند استخدام الأعداد الصحيحة أو العشرية لبناء نسخة الكائن تجري عملية تحويل القيمة نفسها إلى النوع decimal. تتضمن الأعداد العشرية decimal قيمًا خاصّة مثل <code>NaN</code> وهي اختصار "Not a number"، وقيمة ما لانهاية الموجبة والسالبة، و ‎<code>-0</code>.
+
</syntaxhighlight>يمكن بناء نسخ الكائن decimal من [[Python/int|الأعداد الصحيحة]]، أو [[Python/str|السلاسل النصية]]، أو [[Python/float|الأعداد العشرية floats]] أو [[Python/tuples|الصفوف tuples]]. عند استخدام الأعداد الصحيحة أو العشرية لبناء نسخة الكائن تجري عملية تحويل القيمة نفسها إلى النوع decimal. تتضمن الأعداد العشرية decimal قيمًا خاصّة مثل <code>NaN</code> وهي اختصار "Not a number"، وقيمة ما لانهاية الموجبة والسالبة، و ‎<code>-0</code>.
  
== مثا ==
+
== أمثلة ==
<syntaxhighlight lang="python3">
+
أمثلة نموذجية عن استخدام الوحدة Decimal لإجراء العمليات الأساسية على الأعداد العشرية:<syntaxhighlight lang="python3">
 
>>> getcontext().prec = 28
 
>>> getcontext().prec = 28
 
 
>>> Decimal(10)
 
>>> Decimal(10)
 
 
Decimal('10')
 
Decimal('10')
 
 
>>> Decimal('3.14')
 
>>> Decimal('3.14')
 
 
Decimal('3.14')
 
Decimal('3.14')
 
 
>>> Decimal(3.14)
 
>>> Decimal(3.14)
 
 
Decimal('3.140000000000000124344978758017532527446746826171875')
 
Decimal('3.140000000000000124344978758017532527446746826171875')
 
 
>>> Decimal((0, (3, 1, 4), -2))
 
>>> Decimal((0, (3, 1, 4), -2))
 
 
Decimal('3.14')
 
Decimal('3.14')
 
 
>>> Decimal(str(2.0 ** 0.5))
 
>>> Decimal(str(2.0 ** 0.5))
 
 
Decimal('1.4142135623730951')
 
Decimal('1.4142135623730951')
 
 
>>> Decimal(2) ** Decimal('0.5')
 
>>> Decimal(2) ** Decimal('0.5')
 
 
Decimal('1.414213562373095048801688724')
 
Decimal('1.414213562373095048801688724')
 
 
>>> Decimal('NaN')
 
>>> Decimal('NaN')
 
 
Decimal('NaN')
 
Decimal('NaN')
 
 
>>> Decimal('-Infinity')
 
>>> Decimal('-Infinity')
 
 
Decimal('-Infinity')
 
Decimal('-Infinity')
 
+
</syntaxhighlight>في حال التقاط إشارة <code>FloatOperation</code> فسيؤدي المزج بين نوعي الأعداد العشرية decimals و <nowiki/>[[Python/floats|floats]] في بناء نسخة الكائن أو في معاملات المقارنة إلى إطلاق استثناء:<syntaxhighlight lang="python3">
</syntaxhighlight>في حال التقاط إشارة <code>FloatOperation</code> يؤدي المزج بين نوعي الأعداد العشرية decimals وfloats في بناء نسخة الكائن أو في [[معاملات المقارنة في بايثون|معاملات المقارنة]] إلى إطلاق استثناء:<syntaxhighlight lang="python3">
 
 
>>> c = getcontext()
 
>>> c = getcontext()
 
 
>>> c.traps[FloatOperation] = True
 
>>> c.traps[FloatOperation] = True
 
 
>>> Decimal(3.14)
 
>>> Decimal(3.14)
 
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
 
File "<stdin>", line 1, in <module>
 
File "<stdin>", line 1, in <module>
 
 
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
 
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
 
 
>>> Decimal('3.5') < 3.7
 
>>> Decimal('3.5') < 3.7
 
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
 
File "<stdin>", line 1, in <module>
 
File "<stdin>", line 1, in <module>
 
 
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
 
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
 
 
>>> Decimal('3.5') == 3.5
 
>>> Decimal('3.5') == 3.5
 
 
True
 
True
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
= جديد في الإصدار 3.3 =
+
== الجديد في الإصدار 3.3 ==
 
تحدّد الأعداد المعنوية للعدد العشري الجديد عن طريق عدد الأرقام المدخلة فقط، ويظهر تأثير مقدار الدقة والتقريب عند إجراء العمليات الحسابية فقط.<syntaxhighlight lang="python3">
 
تحدّد الأعداد المعنوية للعدد العشري الجديد عن طريق عدد الأرقام المدخلة فقط، ويظهر تأثير مقدار الدقة والتقريب عند إجراء العمليات الحسابية فقط.<syntaxhighlight lang="python3">
 
>>> getcontext().prec = 6
 
>>> getcontext().prec = 6
 
 
>>> Decimal('3.0')
 
>>> Decimal('3.0')
 
 
Decimal('3.0')
 
Decimal('3.0')
 
 
>>> Decimal('3.1415926535')
 
>>> Decimal('3.1415926535')
 
 
Decimal('3.1415926535')
 
Decimal('3.1415926535')
 
 
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
 
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
 
 
Decimal('5.85987')
 
Decimal('5.85987')
 
 
>>> getcontext().rounding = ROUND_UP
 
>>> getcontext().rounding = ROUND_UP
 
 
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
 
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
 
 
Decimal('5.85988')
 
Decimal('5.85988')
  
</syntaxhighlight>تطلق اللغة [[الاستثناءات في بايثون|الاستثناء]] <code>InvalidOperation</code> عند تجاوز الحد المسموح به لدى إنشاء العدد العشري:<syntaxhighlight lang="python3">
+
</syntaxhighlight>تطلق اللغة [[Python/exceptions|الاستثناء]] <code>InvalidOperation</code> عند تجاوز الحد المسموح به لدى إنشاء العدد العشري:<syntaxhighlight lang="python3">
>>>
 
 
 
 
>>> Decimal("1e9999999999999999999")
 
>>> Decimal("1e9999999999999999999")
 
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
 
File "<stdin>", line 1, in <module>
 
File "<stdin>", line 1, in <module>
 
 
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
 
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
 
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== تغيير في الإصدار 3.3 ==
+
== التغييرات في الإصدار 3.3 ==
 
تتفاعل الأعداد العشرية decimals بصورة جيدة مع الأنواع الأخرى للبيانات في بايثون. إليك بعض الأمثلة على ذلك:<syntaxhighlight lang="python3">
 
تتفاعل الأعداد العشرية decimals بصورة جيدة مع الأنواع الأخرى للبيانات في بايثون. إليك بعض الأمثلة على ذلك:<syntaxhighlight lang="python3">
>>>
 
 
 
>>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
 
>>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
 
 
>>> max(data)
 
>>> max(data)
 
 
Decimal('9.25')
 
Decimal('9.25')
 
 
>>> min(data)
 
>>> min(data)
 
 
Decimal('0.03')
 
Decimal('0.03')
 
 
>>> sorted(data)
 
>>> sorted(data)
 
 
[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
 
[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
 
 
Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
 
Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
 
 
>>> sum(data)
 
>>> sum(data)
 
 
Decimal('19.29')
 
Decimal('19.29')
 
 
>>> a,b,c = data[:3]
 
>>> a,b,c = data[:3]
 
 
>>> str(a)
 
>>> str(a)
 
 
'1.34'
 
'1.34'
 
 
>>> float(a)
 
>>> float(a)
 
 
1.34
 
1.34
 
 
>>> round(a, 1)
 
>>> round(a, 1)
 
 
Decimal('1.3')
 
Decimal('1.3')
 
 
>>> int(a)
 
>>> int(a)
 
 
1
 
1
 
 
>>> a * 5
 
>>> a * 5
 
 
Decimal('6.70')
 
Decimal('6.70')
 
 
>>> a * b
 
>>> a * b
 
 
Decimal('2.5058')
 
Decimal('2.5058')
 
 
>>> c % a
 
>>> c % a
 
 
Decimal('0.77')
 
Decimal('0.77')
 
+
</syntaxhighlight>يمكن أيضًا استخدام بعض الدوال الرياضية مع الأعداد العشرية:<syntaxhighlight lang="python3">
 
 
</syntaxhighlight>يمكن أيضًا استخدام بعض [[الدوال الرياضية في بايثون|الدوال الرياضية]] مع الأعداد العشرية:<syntaxhighlight lang="python3">
 
 
>>> getcontext().prec = 28
 
>>> getcontext().prec = 28
 
 
>>> Decimal(2).sqrt()
 
>>> Decimal(2).sqrt()
 
 
Decimal('1.414213562373095048801688724')
 
Decimal('1.414213562373095048801688724')
 
 
>>> Decimal(1).exp()
 
>>> Decimal(1).exp()
 
 
Decimal('2.718281828459045235360287471')
 
Decimal('2.718281828459045235360287471')
 
 
>>> Decimal('10').ln()
 
>>> Decimal('10').ln()
 
 
Decimal('2.302585092994045684017991455')
 
Decimal('2.302585092994045684017991455')
 
 
>>> Decimal('10').log10()
 
>>> Decimal('10').log10()
 
 
Decimal('1')
 
Decimal('1')
 
 
</syntaxhighlight>تقرّب دالة <code>quantize()‎</code> العدد إلى أسّ ثابت، وهي طريقة مفيدة في التطبيقات المحاسبية التي غالبًا ما تقرّب النتائج إلى عدد ثابت من المراتب:<syntaxhighlight lang="python3">
 
</syntaxhighlight>تقرّب دالة <code>quantize()‎</code> العدد إلى أسّ ثابت، وهي طريقة مفيدة في التطبيقات المحاسبية التي غالبًا ما تقرّب النتائج إلى عدد ثابت من المراتب:<syntaxhighlight lang="python3">
 
 
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
 
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
 
 
Decimal('7.32')
 
Decimal('7.32')
 
 
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
 
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
 
 
Decimal('8')
 
Decimal('8')
 
</syntaxhighlight>تتواصل الدالة <code>getcontenxt()‎</code> مع السياق الحالي - كما هو مبين في أعلاه - وتتيح تعديل الخيارات حسب الحاجة، وهذه الطريقة ملائمة لمعظم التطبيقات. يمكن أيضًا إنشاء سياقات بديلة عند الحاجة إلى ذلك باستخدام المشيّد <code>Context()‎</code>، وتستخدم الدالة <code>setcontext()</code>‎ لتفعيل السياق البديل.
 
</syntaxhighlight>تتواصل الدالة <code>getcontenxt()‎</code> مع السياق الحالي - كما هو مبين في أعلاه - وتتيح تعديل الخيارات حسب الحاجة، وهذه الطريقة ملائمة لمعظم التطبيقات. يمكن أيضًا إنشاء سياقات بديلة عند الحاجة إلى ذلك باستخدام المشيّد <code>Context()‎</code>، وتستخدم الدالة <code>setcontext()</code>‎ لتفعيل السياق البديل.
  
وبحسب المعايير التي تعتمدها اللغة، تقدّم [[الوحدات في بايثون|وحدة]] decimal سياقين قياسيين جاهزين للاستخدام هما <code>BasicContext</code> و <code>ExtendedContext</code>. السياق الأوّل مفيد جدًّا في عملية التنقيح debugging لأنّ معظم المصائد تكون مفعّلة:<syntaxhighlight lang="python3">
+
وبحسب المعايير التي تعتمدها اللغة، تقدّم وحدة decimal سياقين قياسيين جاهزين للاستخدام هما <code>BasicContext</code> و <code>ExtendedContext</code>. السياق الأوّل مفيد جدًّا في عملية التنقيح debugging لأنّ معظم المصائد تكون مفعّلة:<syntaxhighlight lang="python3">
 
>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
 
>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
  
سطر 263: سطر 159:
  
 
>>> Decimal(1) / Decimal(7)
 
>>> Decimal(1) / Decimal(7)
 
 
Decimal('0.142857142857142857142857142857142857142857142857142857142857')
 
Decimal('0.142857142857142857142857142857142857142857142857142857142857')
 
 
>>> ExtendedContext
 
>>> ExtendedContext
 
 
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
 
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
 
 
capitals=1, clamp=0, flags=[], traps=[])
 
capitals=1, clamp=0, flags=[], traps=[])
 
 
>>> setcontext(ExtendedContext)
 
>>> setcontext(ExtendedContext)
 
 
>>> Decimal(1) / Decimal(7)
 
>>> Decimal(1) / Decimal(7)
 
 
Decimal('0.142857143')
 
Decimal('0.142857143')
 
 
>>> Decimal(42) / Decimal(0)
 
>>> Decimal(42) / Decimal(0)
 
 
Decimal('Infinity')
 
Decimal('Infinity')
 
 
>>> setcontext(BasicContext)
 
>>> setcontext(BasicContext)
 
 
>>> Decimal(42) / Decimal(0)
 
>>> Decimal(42) / Decimal(0)
 
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
 
File "<pyshell#143>", line 1, in -toplevel-
 
File "<pyshell#143>", line 1, in -toplevel-
 
 
Decimal(42) / Decimal(0)
 
Decimal(42) / Decimal(0)
 
 
DivisionByZero: x / 0
 
DivisionByZero: x / 0
 
 
 
</syntaxhighlight>تمتلك السياقات كذلك رايات إشارة signal flags لمراقبة الحالات الاستثنائية التي تطرأ في أثناء إجراء الحسابات. تبقى الأعلام مفعّلة إلى حين إلغائها يدويًا؛ لذا يفضّل إلغاء الأعلام قبل أي مجموعة من العمليات الحسابية التي تخضع للمراقبة، وذلك باستخدام التابع <code>clear_flags()‎</code>:<syntaxhighlight lang="python3">
 
</syntaxhighlight>تمتلك السياقات كذلك رايات إشارة signal flags لمراقبة الحالات الاستثنائية التي تطرأ في أثناء إجراء الحسابات. تبقى الأعلام مفعّلة إلى حين إلغائها يدويًا؛ لذا يفضّل إلغاء الأعلام قبل أي مجموعة من العمليات الحسابية التي تخضع للمراقبة، وذلك باستخدام التابع <code>clear_flags()‎</code>:<syntaxhighlight lang="python3">
 
>>> setcontext(ExtendedContext)
 
>>> setcontext(ExtendedContext)
 
 
>>> getcontext().clear_flags()
 
>>> getcontext().clear_flags()
 
 
>>> Decimal(355) / Decimal(113)
 
>>> Decimal(355) / Decimal(113)
 
 
Decimal('3.14159292')
 
Decimal('3.14159292')
 
 
>>> getcontext()
 
>>> getcontext()
 
 
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
 
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
 
 
capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])
 
capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])
 
 
</syntaxhighlight>يبيّن مدخل flags أنّ القيمة التقريبية للعدد pi مقرّبة (تخلّصت اللغة من الأرقام التي تتجاوز مقدار دقة السياق) وأن النتيجة غير دقيقة (أي أنّ بعض الأعداد التي تم تجاهلها ليست أصفارًا).
 
</syntaxhighlight>يبيّن مدخل flags أنّ القيمة التقريبية للعدد pi مقرّبة (تخلّصت اللغة من الأرقام التي تتجاوز مقدار دقة السياق) وأن النتيجة غير دقيقة (أي أنّ بعض الأعداد التي تم تجاهلها ليست أصفارًا).
  
يمكن تعيين مصائد مفردة باستخدام [[القواميس في بايثون|القاموس]] في حقل traps الخاص بالسياق:<syntaxhighlight lang="python3">
+
يمكن تعيين مصائد مفردة باستخدام [[Python/dict|القاموس]] في حقل traps الخاص بالسياق:<syntaxhighlight lang="python3">
 
>>> setcontext(ExtendedContext)
 
>>> setcontext(ExtendedContext)
 
 
>>> Decimal(1) / Decimal(0)
 
>>> Decimal(1) / Decimal(0)
 
 
Decimal('Infinity')
 
Decimal('Infinity')
 
 
>>> getcontext().traps[DivisionByZero] = 1
 
>>> getcontext().traps[DivisionByZero] = 1
 
 
>>> Decimal(1) / Decimal(0)
 
>>> Decimal(1) / Decimal(0)
 
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
 
File "<pyshell#112>", line 1, in -toplevel-
 
File "<pyshell#112>", line 1, in -toplevel-
 
 
Decimal(1) / Decimal(0)
 
Decimal(1) / Decimal(0)
 
 
DivisionByZero: x / 0
 
DivisionByZero: x / 0
</syntaxhighlight><span> </span>
+
</syntaxhighlight><span> </span>تعدّل معظم البرامج السياق الحالي مرة واحدة فقط في بداية البرنامج، وتجري عملية تحويل البيانات إلى أعداد عشرية decimal في معظم البرامج دفعة واحدة باستخدام حلقة تكرارية. وبعد تعيين السياق وإنشاء الأعداد العشرية تعالج اللغة البيانات بنفس الطريقة التي تعالج بها الأنواع الرقمية الأخرى.
  
تعدّل معظم البرامج السياق الحالي مرة واحدة فقط في بداية البرنامج، وتجري عملية تحويل البيانات إلى أعداد عشرية decimal في معظم البرامج دفعة واحدة باستخدام حلقة تكرارية. وبعد تعيين السياق وإنشاء الأعداد العشرية تعالج اللغة البيانات بنفس الطريقة التي تعالج بها الأنواع الرقمية الأخرى.
+
== انظر أيضًا ==
 +
* [[Python/int|الأعداد الصحيحة int في بايثون]].
 +
* [[Python/float|الأعداد العشرية float في بايثون]].
 +
* [[Python/fraction|الأعداد الكسرية في بايثون]].
 +
* [[Python/complex|الأعداد المركبة في بايثون]].
  
 
== مصادر ==
 
== مصادر ==

المراجعة الحالية بتاريخ 07:55، 22 أغسطس 2018

تتيح وحدة decimal إجراء حسابات سريعة على الأعداد العشرية مع ضمان التقريب الصحيح.

>>> import decimal
>>> Decimal(10)
Decimal('10')
>>> Decimal('3.14')
Decimal('3.14')
>>> Decimal(3.14)
Decimal('3.140000000000000124344978758017532527446746826171875')

ميزات الوحدة decimal

تتفوق هذه الوحدة على نوع الأعداد العشرية float بعدة ميزات:

  • العدد العشري decimal "يستند إلى نموذج أعداد عشرية ذات فاصلة عائمة يراعي الاستخدام البشري ويلتزم بمبدأ أساسي هو أنّه يجب أن توفّر الحواسيب عمليات حسابية تعمل بنفس الطريقة التي يتعلّمها الناس في المدارس" - اقتباسٌ من مواصفات العمليات الحسابية التي تجرى على الأعداد العشرية decimal.
  • يمكن تمثيل الأعداد العشرية decimal بدقّة، أما الأرقام مثل 1.1 و 2.2 فلا تمثل تمثيلًا دقيقًا في النظام الثنائي للأعداد ذات الفاصلة العائمة. ولا يتوقع المستخدم أن تعطي العملية الحسابية ‎1.1 + 2.2‎ النتيجة 3.3000000000000003 كما هو الحال مع الأعداد في النظام الثنائي للأعداد ذات الفاصلة العائمة.
  • تحافظ الأعداد العشرية decimal على الدقة عند إجراء العمليات الحسابية، ففي هذا النظام يكون ناتج العمليات التالية: ‎0.1 + 0.1 + 0.1 - 0.3 هو الصفر، أما في النظام الثنائي للفاصلة العائمة يكون الناتج 5.5511151231257827e-017. صحيح أن هذا الرقم قريب جدًّا من الصفر، ولكن تعيق هذه الفروقات إجراء عمليات مقارنة دقيقة للمساواة إلى جانب أنّ هذه الفروقات يمكن أن تتزايد مع الاستمرار في إجراء العمليات الحسابية؛ لذا يفضل استخدام النوع decimal في التطبيقات المحاسبية التي تتطلّب إجراء مقارنات مساواة صارمة.
  • تعتمد وحدة decimal مفهوم الأعداد المعنوية (significant places)؛ لذا فإنّ ناتج العملية ‎1.30 + 1.20 هو 2.50، إذ تحتفظ اللغة بالصفر الأخير إشارة إلى أنّه عدد معنوي. مفهوم الأعداد المعنوية هو من المفاهيم الشائعة لتمثيل الأرقام في التطبيقات المالية والمحاسبية. وفي عملية الضرب تستخدم جميع الأرقام للحصول على الناتج، فعلى سبيل المثال تعطي العملية ‎1.3 * 1.2 الناتج 1.56 أما العملية ‎1.30 * 1.20 فتعطي الناتج 1.5600.
  • على عكس الأعداد العشرية ذات الفاصلة العائمة، يمكن تحديد مقدار الدقة المعتمدة في الأعداد العشرية decimal من قبل المستخدم (القيمة الافتراضية هي 28 مرتبة) ويمكن استخدام أي عدد مهما كان كبيرًا، مثال:
>>> from decimal import *
>>> getcontext().prec = 6
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')
>>> getcontext().prec = 28
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571428571428571428571429')
  • تستخدم الأعداد العشرية بنوعيها float و decimal في بايثون بالاعتماد على المعايير المعروفة، ويعرض النوع float جزءًا بسيطًا من هذه المعايير، في حين أنّ وحدة decimal تعرض جميع الأجزاء المطلوبة ضمن هذه المعايير. ويمكن للمبرمج - عند الحاجة - أن يسيطر بصورة تامة على عمليات التقريب والتعامل مع الإشارات signals، ويمكن كذلك فرض عمليات حسابية دقيقة ومضبوطة باستخدام استثناءات توقف تنفيذ أي عملية حسابية غير دقيقة.
  • صمّمت وحدة decimal لتدعم كلًّا من العمليات الحسابية على الأرقام العشرية غير المقرّبة الدقيقة (تسمى في بعض الأحيان العمليات الحسابية على الأعداد ذات الفاصلة الثابتة [fixed-point arithmetics]) والعمليات الحسابية على الأعداد ذات الفاصلة العائمة المقرّبة.

يتمحور تصميم وحدة decimal على ثلاثة مفاهيم أساسية: العدد العشري، والسياق (context) الخاص بالعملية الحسابية، والإشارة (signal).

العدد العشري غير قابل للتغيير (immutable)، ويمتلك إشارةً وأعداد coefficient وأسًّا. وللحفاظ على الأعداد المعنوية لا تحذف اللغة الأصفار الأخيرة في الرقم. تضمّ الأعداد العشرية decimals كذلك قيمًا خاصّة مثل Infinity، و ‎-Infinity و NaN، وتميّز أيضًا بين القيمتين ‎-0 و ‎+0.

يمثّل سياق العمليات الحسابية بيئة تحدّد الدقة، وقواعد التقريب، وحدود الأسس (exponents)، ورايات (flags) تحدّد نتائج العمليات، ومفعّلات المصائد (trap enablers) تحدّد ما إذا كانت الإشارة تعامل معاملة الاستثناءات (exceptions). تقدّم اللغة خيارات التقريب التالية: ROUND_CEILING و ROUND_DOWN و ROUND_FLOOR و ROUND_HALF_DOWN و ROUND_HALF_EVEN و ROUND_HALF_UP و ROUND_UP و ROUND_05UP.

الإشارات هي مجموعة من الشروط الاستثنائية التي تظهر أثناء إجراء العمليات الحسابية. ويمكن تجاهل هذه الإشارات، أو عدّها مصدرًا للمعلومات، أو معاملتها كاستثناءات وذلك حسب الحاجة. تقدّم اللغة الإشارات التالية في وحدة decimal: ‏Underflow و Overflow و Subnormal و Rounded و Inexact و DivisionByZero و InvalidOperation و Clamped و FloatOperation.

لكل راية هناك trap enabler، وعندما ظهور إشارة يتم تعيين القيمة 1 للراية الخاصة بها، وبعد ذلك إن تم تعيين القيمة 1 لـ trap enabler تطلق اللغة استثناءً. تبقى قيمة الرايات ثابتة ويجب على المستخدم إعادة تعيين قيمتها قبل مراقبة الحسابات مرة أخرى.

راجع أيضًا: مواصفات IBM العامة للعمليات الحسابية على الأعداد العشرية، المواصفة العامة للعمليات الحسابية على الأعداد العشرية.

استخدام وحدة decimal

لاستخدام وحدة decimal يجب في البداية استيرادها، واستعراض السياق الحالي باستخدام الدالة getcontext()‎ وتعيين قيم جديدة لمقدار الدقة والتقريب والمصائد المفعّلة (enabled traps)، مثال:

>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
InvalidOperation])
>>> getcontext().prec = 7 # تعيين مقدار جديد للدقة

يمكن بناء نسخ الكائن decimal من الأعداد الصحيحة، أو السلاسل النصية، أو الأعداد العشرية floats أو الصفوف tuples. عند استخدام الأعداد الصحيحة أو العشرية لبناء نسخة الكائن تجري عملية تحويل القيمة نفسها إلى النوع decimal. تتضمن الأعداد العشرية decimal قيمًا خاصّة مثل NaN وهي اختصار "Not a number"، وقيمة ما لانهاية الموجبة والسالبة، و ‎-0.

أمثلة

أمثلة نموذجية عن استخدام الوحدة Decimal لإجراء العمليات الأساسية على الأعداد العشرية:

>>> getcontext().prec = 28
>>> Decimal(10)
Decimal('10')
>>> Decimal('3.14')
Decimal('3.14')
>>> Decimal(3.14)
Decimal('3.140000000000000124344978758017532527446746826171875')
>>> Decimal((0, (3, 1, 4), -2))
Decimal('3.14')
>>> Decimal(str(2.0 ** 0.5))
Decimal('1.4142135623730951')
>>> Decimal(2) ** Decimal('0.5')
Decimal('1.414213562373095048801688724')
>>> Decimal('NaN')
Decimal('NaN')
>>> Decimal('-Infinity')
Decimal('-Infinity')

في حال التقاط إشارة FloatOperation فسيؤدي المزج بين نوعي الأعداد العشرية decimals و floats في بناء نسخة الكائن أو في معاملات المقارنة إلى إطلاق استثناء:

>>> c = getcontext()
>>> c.traps[FloatOperation] = True
>>> Decimal(3.14)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
>>> Decimal('3.5') < 3.7
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
>>> Decimal('3.5') == 3.5
True

الجديد في الإصدار 3.3

تحدّد الأعداد المعنوية للعدد العشري الجديد عن طريق عدد الأرقام المدخلة فقط، ويظهر تأثير مقدار الدقة والتقريب عند إجراء العمليات الحسابية فقط.

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

تطلق اللغة الاستثناء InvalidOperation عند تجاوز الحد المسموح به لدى إنشاء العدد العشري:

>>> Decimal("1e9999999999999999999")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

التغييرات في الإصدار 3.3

تتفاعل الأعداد العشرية decimals بصورة جيدة مع الأنواع الأخرى للبيانات في بايثون. إليك بعض الأمثلة على ذلك:

>>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
>>> max(data)
Decimal('9.25')
>>> min(data)
Decimal('0.03')
>>> sorted(data)
[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
>>> sum(data)
Decimal('19.29')
>>> a,b,c = data[:3]
>>> str(a)
'1.34'
>>> float(a)
1.34
>>> round(a, 1)
Decimal('1.3')
>>> int(a)
1
>>> a * 5
Decimal('6.70')
>>> a * b
Decimal('2.5058')
>>> c % a
Decimal('0.77')

يمكن أيضًا استخدام بعض الدوال الرياضية مع الأعداد العشرية:

>>> getcontext().prec = 28
>>> Decimal(2).sqrt()
Decimal('1.414213562373095048801688724')
>>> Decimal(1).exp()
Decimal('2.718281828459045235360287471')
>>> Decimal('10').ln()
Decimal('2.302585092994045684017991455')
>>> Decimal('10').log10()
Decimal('1')

تقرّب دالة quantize()‎ العدد إلى أسّ ثابت، وهي طريقة مفيدة في التطبيقات المحاسبية التي غالبًا ما تقرّب النتائج إلى عدد ثابت من المراتب:

>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
Decimal('8')

تتواصل الدالة getcontenxt()‎ مع السياق الحالي - كما هو مبين في أعلاه - وتتيح تعديل الخيارات حسب الحاجة، وهذه الطريقة ملائمة لمعظم التطبيقات. يمكن أيضًا إنشاء سياقات بديلة عند الحاجة إلى ذلك باستخدام المشيّد Context()‎، وتستخدم الدالة setcontext()‎ لتفعيل السياق البديل. وبحسب المعايير التي تعتمدها اللغة، تقدّم وحدة decimal سياقين قياسيين جاهزين للاستخدام هما BasicContext و ExtendedContext. السياق الأوّل مفيد جدًّا في عملية التنقيح debugging لأنّ معظم المصائد تكون مفعّلة:

>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)

>>> setcontext(myothercontext)

>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857142857142857142857142857')
>>> ExtendedContext
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
capitals=1, clamp=0, flags=[], traps=[])
>>> setcontext(ExtendedContext)
>>> Decimal(1) / Decimal(7)
Decimal('0.142857143')
>>> Decimal(42) / Decimal(0)
Decimal('Infinity')
>>> setcontext(BasicContext)
>>> Decimal(42) / Decimal(0)
Traceback (most recent call last):
File "<pyshell#143>", line 1, in -toplevel-
Decimal(42) / Decimal(0)
DivisionByZero: x / 0

تمتلك السياقات كذلك رايات إشارة signal flags لمراقبة الحالات الاستثنائية التي تطرأ في أثناء إجراء الحسابات. تبقى الأعلام مفعّلة إلى حين إلغائها يدويًا؛ لذا يفضّل إلغاء الأعلام قبل أي مجموعة من العمليات الحسابية التي تخضع للمراقبة، وذلك باستخدام التابع clear_flags()‎:

>>> setcontext(ExtendedContext)
>>> getcontext().clear_flags()
>>> Decimal(355) / Decimal(113)
Decimal('3.14159292')
>>> getcontext()
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])

يبيّن مدخل flags أنّ القيمة التقريبية للعدد pi مقرّبة (تخلّصت اللغة من الأرقام التي تتجاوز مقدار دقة السياق) وأن النتيجة غير دقيقة (أي أنّ بعض الأعداد التي تم تجاهلها ليست أصفارًا). يمكن تعيين مصائد مفردة باستخدام القاموس في حقل traps الخاص بالسياق:

>>> setcontext(ExtendedContext)
>>> Decimal(1) / Decimal(0)
Decimal('Infinity')
>>> getcontext().traps[DivisionByZero] = 1
>>> Decimal(1) / Decimal(0)
Traceback (most recent call last):
File "<pyshell#112>", line 1, in -toplevel-
Decimal(1) / Decimal(0)
DivisionByZero: x / 0

تعدّل معظم البرامج السياق الحالي مرة واحدة فقط في بداية البرنامج، وتجري عملية تحويل البيانات إلى أعداد عشرية decimal في معظم البرامج دفعة واحدة باستخدام حلقة تكرارية. وبعد تعيين السياق وإنشاء الأعداد العشرية تعالج اللغة البيانات بنفس الطريقة التي تعالج بها الأنواع الرقمية الأخرى.

انظر أيضًا

مصادر