سؤال

في نهاية الأسبوع الماضي، غيرت WebHosts لموقع الويب الخاص بي. كان الخادم المضيف الذي كنت في نظام تشغيل 32 بت والثانية التي انتقلت إليها هي 64 بت. بشكل غير متوقع، بدأت بعض البرامج النصية الخاصة بي PHP بإعطاء نتائج غير صحيحة.

في حالتي << و >> كانت العمليات (تحول بت) الجاني. لقد انتهيت من الاضطرار إلى إخفاء النتيجة مع 0xFFFFFFFFF ثم تغيير النتيجة إذا كانت سلبية بالنسبة لها للعمل كما فعلت من قبل.

هل هناك أي مشاكل أخرى محتملة في البرامج النصية PHP الخاصة بي يجب أن أبحث عنه؟

هل كانت مفيدة؟

المحلول

إنها لغة رفيعة المستوى، لذا فإن أي شيء غير مرتبط قليلا (مشغلي bitwise، bitshift) سيكون هو نفسه.

نصائح أخرى

قد يكون عدد صحيح 64 بت بدلا من 32 بت. هناك بعض غريب حالات حيث قد يسبب هذا مشاكل.

يتطلب معالجة بت العناية الخاصة لجعل المحمولة بين الأنظمة / الهندسة.

في C، << و >> يمكن إجراء عمليات المحمولة باستخدام غير موقعة المتغيرات، التي تزيل قواعد مجاملة تلك / TWOs للأرقام السالبة.

كقاعدة عامة، لا تستخدم أقنعة الطول الثابت لمعالجة البت (مثل & و |). هذه هي الهندسة المعمارية تعتمد.

على سبيل المثال إعادة تعيين آخر 4 بت: سيعمل القناع 0xF0 على بنية 8 بت، ولكن ليس 16 بت. ستكون النتائج مختلفة (قد يكون لدى 16 بت تناول أجزاء أخرى يتم تعيينها غير المدرجة في القناع).

للتغلب على هذه المشكلة، الاستفادة من المشغل ~. القناع ~ 0xf يعادل 0xF0، ولكن سوف تعمل على أي هندسة معمارية. جميع البتات باستثناء آخر 4 سيتم إعادة تعيين

يتصرف strtotime بشكل مختلف عن 64 بت. من php.net:

ملحوظة:

مجموعة صالحة من timestamp هو عادة من FRI، 13 ديسمبر 19:45:54 UTC To Tue، 19 يناير 2038 03:14:07 UTC. (هذه هي التواريخ التي تتوافق مع القيم الدنيا والحد الأقصى لعدد صحيح موقعة 32 بت.) بالإضافة إلى ذلك، لا تدعم جميع المنصات الطوابع الزمنية السلبية، وبالتالي قد يقتصر نطاق تاريخك على أي وقت سابق من Enix Epoch. هذا يعني أن التواريخ السابقة قبل 1 يناير، 1970 لن تعمل على Windows وبعض توزيعات Linux وبعض أنظمة التشغيل الأخرى. إصدارات PHP 5.1.0 والأحدث تتغلب على هذا القيد.

بالنسبة لإصدارات 64 بت من PHP، فإن النطاق الصالح للقطاع الزمني هو لانهائي فعال، حيث يمكن أن تمثل 64 بت تقريبا 293 مليار سنة في أي من الاتجاهين.

كان لدينا كود كان يقوم به strtotime ('0000-00-00') ومن المتوقع أن تكون النتيجة خاطئة، عندما انتقلنا إلى 64 بت عددا عدد صحيح سلبي.

المشكلة الوحيدة التي ستشاهدها هي عندما تعتمد على التمثيل الثنائي 32 بت من البيانات. أساسا لأن PHP يستخدم أعداد صحيحة موقعة، سترى مشكلات في التجزئة، والجيل الرئيسي، إلخ ... عند صب صراحة إلى Int مع (int)، سوف تلتف الأرقام> 2 ^ 32 أينما لن تلتف في بيئة 64 بت ما لم تكن> 2 ^ 64 بالطبع.

4 vs 8 بت مثال:

مشاكل القيمة العشرية:

     0010 >> 1 =      0001   [ 1 dec ]
0000 0010 >> 1 = 0000 0001   [ 1 dec ]

هؤلاء كلاهما ينتجون نفس النتيجة (الحكم العشري)، ومع ذلك:

     0100 << 1 =      1000   [ -8 dec ]
0000 0100 << 1 = 0000 1000   [ 16 dec ]

مشاكل التفاف:

     1000 << 1 =      0000   [  0 dec ]
0000 1000 << 1 = 0001 0000   [ 32 dec ]

سيتم التعامل مع جميع أجهزة المشاريع عدد صحيح / الفاصلة العائمة كقيم 64 بت، لذلك إذا كانت النتيجة النهائية تعتمد على قطع 32 بتسيت، فسيتعين عليك التعويض عن هذا.

ستتأثر نتائج شعبة النقطة العائمة بزيادة إلى 64 بت؛ لذلك إذا كان لديك رمز يقوم بشيء غبي مثل مقارنة نتائج شعبة النقطة العائمة إلى الثوابت الصغار، فنتوقع من كسرها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top