الفرق بين المراجعتين لصفحة: «Python/decimal»
لا ملخص تعديل |
لا ملخص تعديل |
||
سطر 11: | سطر 11: | ||
== ميزات الوحدة decimal == | == ميزات الوحدة decimal == | ||
تتفوق هذه [[Python/modules|الوحدة]] على نوع الأعداد العشرية float بعدة ميزات: | تتفوق هذه [[Python/modules|الوحدة]] على نوع [[Python/float|الأعداد العشرية float]] بعدة ميزات: | ||
* العدد العشري decimal "يستند إلى نموذج أعداد عشرية ذات فاصلة عائمة يراعي الاستخدام البشري ويلتزم بمبدأ أساسي هو أنّه يجب أن توفّر الحواسيب عمليات حسابية تعمل بنفس الطريقة التي يتعلّمها الناس في المدارس" - اقتباسٌ من مواصفات العمليات الحسابية التي تجرى على الأعداد العشرية decimal. | * العدد العشري decimal "يستند إلى نموذج أعداد عشرية ذات فاصلة عائمة يراعي الاستخدام البشري ويلتزم بمبدأ أساسي هو أنّه يجب أن توفّر الحواسيب عمليات حسابية تعمل بنفس الطريقة التي يتعلّمها الناس في المدارس" - اقتباسٌ من مواصفات العمليات الحسابية التي تجرى على الأعداد العشرية decimal. | ||
سطر 37: | سطر 37: | ||
العدد العشري غير قابل للتغيير (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</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>. | يمثّل سياق العمليات الحسابية بيئة تحدّد الدقة، وقواعد التقريب، وحدود الأسس (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: <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>. | الإشارات هي مجموعة من الشروط الاستثنائية التي تظهر أثناء إجراء العمليات الحسابية. ويمكن تجاهل هذه الإشارات، أو عدّها مصدرًا للمعلومات، أو معاملتها [[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>. | ||
لكل راية هناك trap enabler، وعندما ظهور إشارة يتم تعيين القيمة <code>1</code> للراية الخاصة بها، وبعد ذلك إن تم تعيين القيمة <code>1</code> لـ trap enabler تطلق اللغة استثناءً. تبقى قيمة الرايات ثابتة ويجب على المستخدم إعادة تعيين قيمتها قبل مراقبة الحسابات مرة أخرى. | لكل راية هناك trap enabler، وعندما ظهور إشارة يتم تعيين القيمة <code>1</code> للراية الخاصة بها، وبعد ذلك إن تم تعيين القيمة <code>1</code> لـ trap enabler تطلق اللغة استثناءً. تبقى قيمة الرايات ثابتة ويجب على المستخدم إعادة تعيين قيمتها قبل مراقبة الحسابات مرة أخرى. | ||
سطر 74: | سطر 74: | ||
>>> Decimal('-Infinity') | >>> Decimal('-Infinity') | ||
Decimal('-Infinity') | Decimal('-Infinity') | ||
</syntaxhighlight>في حال التقاط إشارة <code>FloatOperation</code> فسيؤدي المزج بين نوعي الأعداد العشرية decimals | </syntaxhighlight>في حال التقاط إشارة <code>FloatOperation</code> فسيؤدي المزج بين نوعي الأعداد العشرية decimals و<nowiki/>[[Python/floats|floats]] في بناء نسخة الكائن أو في معاملات المقارنة إلى إطلاق استثناء:<syntaxhighlight lang="python3"> | ||
>>> c = getcontext() | >>> c = getcontext() | ||
>>> c.traps[FloatOperation] = True | >>> c.traps[FloatOperation] = True | ||
سطر 103: | سطر 103: | ||
</syntaxhighlight>تطلق اللغة [[Python/exceptions|الاستثناء]] <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): | ||
سطر 112: | سطر 111: | ||
== التغييرات في الإصدار 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) | ||
سطر 186: | سطر 184: | ||
</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) |
مراجعة 22:17، 17 مايو 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
.
مثال
>>> 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 في معظم البرامج دفعة واحدة باستخدام حلقة تكرارية. وبعد تعيين السياق وإنشاء الأعداد العشرية تعالج اللغة البيانات بنفس الطريقة التي تعالج بها الأنواع الرقمية الأخرى.
مصادر
- صفحة Decimal fixed point and floating point arithmetic في توثيق بايثون الرسمي.