PHP المختصة بالبت اليسار يتحول 32 المساحات المشكلة والنتائج السيئة مع أعداد كبيرة العمليات الحسابية

StackOverflow https://stackoverflow.com/questions/2461894

  •  20-09-2019
  •  | 
  •  

سؤال

ولدي المشاكل التالية:

أولا: أسعى للقيام 32 المساحات المختصة بالبت التحول الأيسر على عدد كبير، ولسبب ما يتم إرجاع عدد دائما كما هو. على سبيل المثال:

echo(516103988<<32); // echoes 516103988

ولأن تحويل بت إلى مسافة واحدة الأيسر هو ما يعادل ضرب من قبل 2، حاولت ضرب عدد 2 ^ 32، ويعمل، فإنه يعود 2216649749795176448.

ثانيا: لا بد لي من إضافة 9379 إلى عدد من وجهة أعلاه:

printf('%0.0f', 2216649749795176448 + 9379); // prints 2216649749795185920 

ويجب طباعة: 2216649749795185827

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

المحلول 2

وبناء على اقتراحات باسكال MARTIN، وحاولت كل من BCMath وتمديد GMP وجاء مع الحلول التالية:

ومع BCMath:

$a = 516103988;
$s = bcpow(2, 32);    
$a = bcadd(bcmul($a, $s), 9379);
echo $a; // works, echoes 2216649749795185827

ومع GMP:

$a = gmp_init(516103988); 
$s = gmp_pow(gmp_init(2), 32); 
$a = gmp_add(gmp_mul($a, $s), gmp_init(9379)); 
echo gmp_strval($a);  // also works

ومن ما أفهم، هناك فرصة أكبر بكثير لBCMath ليتم تثبيتها على الخادم ثم GMP، ولذا فإنني سوف يكون باستخدام الحل الأول.

والشكر:)

نصائح أخرى

وبى صحيح الدقة يقتصر على حجم الكلمة آلة (32، 64). للعمل مع الأعداد الصحيحة الدقة التعسفي لديك لتخزينها كسلاسل واستخدام قبل الميلاد مكتبة أو برنامج الرصد العالمي:

   echo bcmul('516103988', bcpow(2, 32));  // 2216649749795176448

والقيام 32 عمليات تحويل بعض الشيء ربما لن عمل مثل تتوقع، كما تميل الأعداد الصحيحة ليتم تخزينها على 32 بت.

ونقلا عن هذه الصفحة: المختصة بالبت مشغلي

<اقتباس فقرة>   

والتحول لا حق لأكثر من 32   بت على 32 بت أنظمة.
لا تترك   التحول في حال النتائج إلى عدد   أطول من 32 بت.
استخدام وظائف   عن تمديد برنامج الرصد العالمي للالمختصة بالبت   التلاعب في الأرقام وراء   PHP_INT_MAX.

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