لم يزد طول مثالنا، لكن تغير عددان في الناتج.
الفراغ يحمل نوعًا أيضًا
إلحاق فراغ افتراضي بمصفوفة int64 قد ينتج float64؛ append لا تعدّل الأصل في مكانه. [1]
إذا كانت القائمة المضافة خالية، يبقى عدد العناصر كما كان. لكن سؤالنا عن حفظ الأعداد الموجودة، لا عن زيادة الطول وحدها: هل يمكن أن تتغير قيمة مخزنة مع أن عدد العناصر المضافة صفر؟
نقارن ثلاثة مسارات: قائمة Python فارغة، ومصفوفة فارغة من float64، ومصفوفة فارغة من int64. المدخل الأصلي واحد، ونحتفظ ببايتاته قبل الاستدعاءات وبعدها.
الأعداد مؤلفة. نستعمل مثالًا صغيرًا في عدد خاناته وكبيرًا في مقدار بعض أعداده.
ثلاثة عناصر قبل الإلحاق وبعده
شغّلنا NumPy 2.3.5 على CPython 3.12.14. حسبنا N=2**53 باستعمال عدد Python صحيح؛ قيمته 9007199254740992. ثم أنشأنا x=np.array([N+1,-(N+1),N+2],dtype=np.int64).
أعداد x هي 9007199254740993 و-9007199254740993 و9007199254740994. شكلها (3,) ونوعها int64؛ لم نمررها أولًا عبر قائمة من أعداد Python العائمة.
شغّلنا y=np.append(x,[]) دون axis. كان نوع y هو float64 وشكلها (3,). قرأنا أعدادها العائمة كقيم صحيحة ممثلة: 9007199254740992 و-9007199254740992 و9007199254740994.
لم نضف خانة رابعة. لكن العنصر الأول صار أقل من أصله بواحد، والثاني صار أكبر بواحد، والثالث بقي كما هو. احتسبنا الفروق بأعداد Python صحيحة بعد قراءة كل قيمة، لا بطرح مصفوفتين مختلطتي النوع.
فحصنا أيضًا النسب الدقيقة الناتجة من y.tolist(). في العنصر الأول كانت (9007199254740992,1)، وفي الثاني (-9007199254740992,1)، وفي الثالث (9007199254740994,1). لا نعتمد على عدد المحارف التي يختارها عرض المصفوفة.
بقيت قيم x ونوعها وشكلها وبايتاتها ثابتة. تغير الناتج لا يعني أن الاستدعاء أعاد كتابة المدخل الأصلي؛ نسجل الطرفين كلًا على حدة.
فراغان مصرح بنوعهما وتحكم صغير
أنشأنا ef=np.array([],dtype=np.float64) وei=np.array([],dtype=np.int64). كلاهما بالشكل (0,) وبلا عناصر؛ يختلف النوع المعلن فقط.
شغّلنا f=np.append(x,ef) فكان من float64، وتطابقت بايتاته وشكله مع y. لم تنفرد قائمة Python الفارغة بهذا الناتج في تحكمنا.
أما z=np.append(x,ei) فبقي من int64 وبالشكل (3,)، وأعاد الأعداد الأصلية الثلاثة بالضبط. احتفظ الفراغ في هذا المسار بالنوع المناسب للمدخل الذي نختبره.
لا نقول إن إضافة أي شيء مصرح بنوعه آمنة لكل حالة. المقارنة هنا لفراغين محددين ومدخل int64 معلن، وليست توصية بتحويل نتيجة عائمة فقدت فرقًا إلى صحيح لاستعادته.
لتحكم القيم الصغيرة، أخذنا مصفوفة int64 بالأعداد [-7,0,13] وشغّلنا المسارات نفسها. القائمة الفارغة أعطت float64، لكن قراءة القيم كأعداد صحيحة أعادت -7 و0 و13 دون فرق. بقي المسار ذو الفراغ int64 من int64.
إذن الانتقال إلى float64 لم يغيّر كل عدد اختبرناه؛ والتحكم الصغير وحده كان سيخفي مشكلة العددين الكبيرين. نحفظ نوع الفراغ ونطاق القيم عند مراجعة هذا الاستدعاء.

مرجع صحيح ونطاق معلوم
binary64 بدقة 53 بتًا؛ وas_integer_ratio تعرض القيمة العائمة ككسر دقيق. [2]
بنى مرجعنا المستقل شبكة توقع باستعمال أعداد Python الصحيحة. للعدد n نأخذ مقداره m=abs(n)، وعدد بتاته b=m.bit_length()، ثم خطوة s=2**max(0,b-53). نقسم m على s إلى خارج q وباقٍ r.
إذا كان 2r أصغر من s نبقي q، وإذا كان أكبر نزيده بواحد. عند التعادل نختار الخارج الزوجي بين q وq+1، ثم نضرب في s ونعيد الإشارة. هذا النموذج مستقل عن append والتحويل العائم؛ قارناه بالنطاق المنفذ، ولا نقدمه خوارزمية لكل أنواع NumPy.
عند N+1، الخطوة المرجعية اثنان والجاران N وN+2. اختار النموذج N واتفق مع التشغيل. وعند -(N+1) أعاد -N؛ أما N+2 فكان نقطة في الشبكة وبقي كما هو. راجعنا أيضًا أن النموذج يعطي N+4 للعدد N+3.
اختبرنا الأعداد sign*(2**e+k)، حيث e من 52 إلى 55، وk من -8 إلى 8، وsign إما -1 أو 1. لدينا 4×17×2=136 حالة، كل منها مدخل من عنصر واحد من int64.
لكل حالة ستة فحوص: نوع وشكل خرج القائمة الفارغة؛ وقيمه مقابل المرجع؛ وتطابق خرج الفراغ float64 معه؛ وحفظ القيم والنوع مع الفراغ int64؛ وثبات بايتات وأشكال المدخل والفراغين؛ والنسب الدقيقة لخرج القائمة الفارغة.
أضفنا المثال الرئيسي والتحكم الصغير بهذه الفحوص الستة لكل منهما، وثلاثة فحوص إضافية للمثال، وفحصًا لحفظ القيم الصغيرة. الحساب (136+2)×6+4=832، ومرت جميعها.
لا يستدعي المرجع float أو append أو astype أو دالة ترقية نوع من NumPy لبناء التوقع. قراءة الناتج إلى عدد Python صحيح هي جزء من التحقق من الناتج، وليست طريقة إنشاء الرقم المتوقع.
لم نفحص رتبًا أو أنواعًا أخرى أو محورًا صريحًا أو مجال int64 كله أو ملكية الذاكرة أو الكتابة عبر الناتج أو الأداء. لم نستخدم مقارنة NumPy مختلطة بين int64 وfloat64 لإثبات حفظ العدد الدقيق.
في هذا المثال، صفر عناصر مضافة لا يضمن صفر تغير في القيم الموجودة بالناتج. قارن العدد الدقيق والنوع والشكل، واحفظ المدخل الأصلي للمراجعة.
| المدخل int64 | خرج الفراغ الافتراضي | الفرق الصحيح |
|---|---|---|
| N+1 | N | -1 |
| -(N+1) | -N | 1 |
| N+2 | N+2 | 0 |
للتوسع: التمثيل العددي وفرق الواحد.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
