2010-08-31 5 views
5

मैं पूर्णांकों जो मूल्यों के बीच तैरता: 4000000000-4294967000एक अहस्ताक्षरित के रूप में बड़े 4 बाइट पूर्णांक लिखें, द्विआधारी

(जो एक 4 बाइट अहस्ताक्षरित पूर्णांक के लिए पूर्णांक अधिकतम से कम है) और मैं फाइल करने के लिए इसे सहेजना चाहते , और उसके बाद फिर से पढ़ने के मूल्य

$f = fopen($fileName, 'wb'); fwrite($f, pack('I', $value)); 

यह महत्वपूर्ण है कि फाइल में, मूल्य, सटीक 4 बाइट अहस्ताक्षरित पूर्णांक होना चाहिए, क्योंकि बाहरी उपकरणों डेटा के उस प्रारूप उम्मीद होगी। लेकिन PHP उस बड़े मूल्यों को फ्लोट के रूप में संग्रहीत करता है, और बाइनरी प्रतिनिधित्व को नष्ट कर देता है।

मैं उस प्रारूप में फ़ाइल करने के लिए उन नंबरों को कैसे लिख सकता हूं?

[संपादित करें] @FractalizeR THX इस काम करता है मेरे पास है:

protected static function handleUint($direction, $value) 
{ 
    if($direction == 'encode') 
    { 
     $first2bytes = intval($value/(256 * 256)); 
     $second2bytes = intval($value - $first2bytes); 

     return pack('n2', $first2bytes, $second2bytes); 
    } 
    else 
    { 
     $arr = unpack('n2ints', $value); 
     $value = $arr['ints1'] * (256 * 256) + intval($arr['ints2']) - 1; 
     return $value; 
    } 
} 

लेकिन मैं काफी समझ में न, मैं क्यों लौट मूल्य पर -1 है, और इस द्विआधारी सही उत्पादन किया जाएगा है ?

उत्तर

1

ठीक है, विभाजित है कि 2 2-बाइट संख्या में 4 बाइट संख्या (256 * 256 से पूर्णांक विभाजन पहला शब्द मिलता है और मूल एक से है कि मूल्य घटाना दूसरा एक पाने के लिए करने के लिए) और दो पैक में लिखें।

+0

अरे, thx :) क्या आप जांच सकते हैं कि मेरा कार्यान्वयन सही काम कर रहा है या नहीं? – canni

1

आप अपने int 4 में बाइट्स विभाजित करने के लिए आप कर सकते हैं निम्नलिखित चाहते हैं:

int x = 13434; 
byte[] buff = new byte[] { 
     (byte)((x >> 24) & 0xff), 
     (byte)((x >> 16) & 0xff), 
     (byte)((x >> 8) & 0xff), 
     (byte((x) & 0xff) 
} 

यहां इस्तेमाल किया विधि बिटवाइज़ संचालन कहा जाता है।

देखें: http://en.wikipedia.org/wiki/Bitwise_operation

आशा इस मदद की।

संपादित करें:

मुझे लगता है कि यह कैसे आप PHP में भी ऐसा ही होता है:

$arr = array(
     ((x >> 24) & 0xff), 
     ((x >> 16) & 0xff), 
     ((x >> 8) & 0xff), 
     (x & 0xff) 
); 

देखें: http://php.net/manual/en/language.operators.bitwise.php

+0

यह काफी PHP नहीं है :) –

1

यह एक नाव होने के बारे में चिंता मत करो। यदि यह 2^31 और 2^32-1 के बीच है, तो आपको कोई समस्या नहीं होगी।

PHP फ्लोट्स में 52-बिट मंटिसा है और इसलिए सटीक हानि 32-बिट संख्याओं के बिना स्टोर कर सकते हैं।

आप एक पूर्णांक को एन्कोड करने के लिए pack बताते हैं और आप इसे एक फ्लोट पास करते हैं, यह फ्लोट को एक पूर्णांक में परिवर्तित कर देगा।तैरता जिसका मूल्य 2^31 और 2^32-1 के बीच एक पूर्णांक है, 32-बिट मशीनों पर ऋणात्मक संख्याओं को परिवर्तित हो:

 
$ php -r "var_dump((int) 4000000000);" 
int(-294967296) 

64-बिट मशीन पर, आप एक पूर्णांक भी मिलती है:

 
$ php -r "var_dump((int) 4000000000);" 
int(4000000000) 

लेकिन उनके बाइट प्रतिनिधित्व बिल्कुल वही है। pack दोनों पर यह वही होगा:

 
$ php -r "var_dump(unpack('H*', pack('I', (float) 4000000000)));" 
array(1) { 
    [1]=> 
    string(8) "00286bee" 
} 
संबंधित मुद्दे