تقنية

trunc: هل يبقى صفرها السالب بعد التحويل إلى صحيح؟

−0.75 يعطي −0.0، ثم تعيده رحلة int64 إلى +0.0.
مسار مثالنا يفقد إشارة الصفر بعد التحويل الصحيح.

قد تحذف الجزء الكسري باستخدام trunc، ثم تحول الناتج إلى عدد صحيح وتعيده إلى float64. تساوي القيم قبل التحويل وبعده قد يوحي بأن شيئًا لم يتغير. لكن في مثالنا يفقد الصفر الناتج من −0.75 إشارته السالبة خلال هذا المسار؛ لذلك نفحص سجل الإشارة إلى جانب القيمة.

ماذا يحذف trunc، وماذا نفحص؟

تصف الوثائق trunc بحذف الجزء الكسري من كل قيمة في اتجاه الصفر. هذا يحدد معنى القيمة الناتجة، لكنه لا يجعل اسم «صحيح» في الوصف إعلانًا بأن نوع المصفوفة تحول تلقائيًا إلى نوع صحيح. نختبر النوع الفعلي في مثالنا بدل استنتاجه من الكتابة. [1]

تختبر signbit بت الإشارة، وتعيد نتائج منطقية عنصرًا بعنصر. لا نستبدل قراءة هذا البت بعبارة «أصغر من الصفر» عند تفسير الصفر ذي الإشارة؛ فالسؤال الذي نريد الإجابة عنه متعلق بالتمثيل المحفوظ بعد كل مرحلة. [2]

في binary64 يشغل بت الإشارة الموضع 63. وإذا كانت حقول الأس والكسر صفرية، يحدد هذا البت إشارة الصفر. [3]

ابدأ بكسر سالب غير صفري

أنشأنا المصفوفة x بالقيم [−0.75، 0.75، −2.75، 2.75] والنوع float64، ثم نفذنا r=np.trunc(x). في NumPy 2.3.5 على CPython 3.12.14 سجلنا r بالقيم [−0.0، 0.0، −2.0، 2.0]، والنوع float64 والشكل (4,).

لم ندخل الصفر السالب يدويًا في x؛ نتتبعه بوصفه نتيجة حذف الجزء الكسري من −0.75. أعطى np.signbit(r) القيم [True، False، True، False]، فاحتفظ الموضع الأول بالإشارة السالبة في هذا التشغيل.

سجل خرجنا كلمتي 8000000000000000 و0000000000000000 للصفرين. راجعنا البتات الفعلية إلى جانب علامة الطباعة.

تابع الصفر عبر النوع الصحيح

نفذنا i=r.astype(np.int64)، فظهرت القيم [0، 0، −2، 2]. ثم نفذنا b=i.astype(np.float64)، فظهرت [0.0، 0.0، −2.0، 2.0]. كانت هذه مصفوفة عائمة جديدة في مسارنا؛ لا نعيدها إلى سجل خرج trunc الأصلي.

أعطى np.signbit(b) القيم [False، False، True، False]. وفي المقابل أعطى np.equal(r,b) أربع قيم True. لذلك حافظ المسار على المساواة العددية في كل موضع، لكنه لم يحافظ على إشارة الصفر في الموضع الأول.

عند −2 و+2 بقيت الإشارتان في التحكم، وعند الصفر الموجب بقي البت غير مضبوط. اختلاف الموضع الأول ليس قاعدة تقول إن كل إشارة تختفي عند التحويل؛ بل فقدان محدد لإشارة صفر ناتج من كسر سالب في التجربة.

أربع قيم مع إشارة خرج trunc وإشارة العودة من int64.
المساواة تنجح في الأربع؛ إشارة الصفر الأول تتغير.

كيف تحققنا من النتائج؟

استخدمنا 17 متجهًا مختلفًا: n=24 للمثال الرئيسي، ثم الأعداد الصحيحة من 1 إلى 16. يتكون كل متجه من [−n/32، n/32، −2−n/32، 2+n/32]. جميع المدخلات طبيعية ومنتهية وغير صفرية، وتقع النتائج الصحيحة بأمان داخل مجال int64.

شغّلنا 17 استدعاء trunc، و34 استدعاء تحويل للنوع، و34 استدعاء signbit، و17 استدعاء equal. المجموع 102؛ حفظنا 204 نتائج عددية و204 نتائج منطقية. بقيت بايتات المدخلات الأصلية ثابتة قبل الاستدعاءات وبعدها.

حسب المرجع المستقل الصحيح باتجاه الصفر بكسور Fraction، ثم بنى توقع كلمة الصفر مع إشارته. قارن كل الكلمات العائمة والنتائج الصحيحة والمنطقية دون استخدام الدوال المختبرة لصنع توقعاتها. لم تشمل التجربة أنواعًا أخرى، أو مدخلات صفرية وغير منتهية وتحت طبيعية، أو قيمًا ضخمة، أو out وwhere.

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

المدخلtrunc / float64إشارة truncإشارة العودة من int64المساواة العددية
−0.75−0.0TrueFalseTrue
+0.75+0.0FalseFalseTrue
−2.75−2.0TrueTrueTrue
+2.75+2.0FalseFalseTrue

للتوسع: تقريب المنتصف إلى الزوجي.

المراجع

  1. NumPy trunc
  2. NumPy signbit
  3. Oracle binary64 representation

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