2009-12-17 10 views
7

पाइथन वी.2.5.4 में, फ्लोट के बिट पैटर्न को प्राप्त करें और कुशलतापूर्वक उपयोग करें, मेरे पास एक फ्लोट है, और मैं उस फ्लोट के बिट पैटर्न को प्राप्त करने और कुशलतापूर्वक (एक पूर्णांक के रूप में) करना चाहता हूं।पायथन:

उदाहरण के लिए, मैं

x = 173.3125 

है आईईईई 754 प्रारूप में लगता है, एक्स के बिट पैटर्न (हेक्साडेसिमल में) 432D5000 है।

मैं उस बिट पैटर्न पर & हेरफेर (उदा।, बिटवाई ऑपरेशंस निष्पादित) कैसे प्राप्त कर सकता हूं?

उत्तर

11

आप जिस स्ट्रिंग को चाहते हैं उसे प्राप्त कर सकते हैं (स्पष्ट रूप से एक बड़े-एंडियन, 32-बिट प्रतिनिधित्व का अर्थ है; अजगर आंतरिक struct मॉड्यूल के साथ देशी endianity और तैरता के लिए 64-बिट) का उपयोग करता है:

>>> import struct 
>>> x = 173.125 
>>> s = struct.pack('>f', x) 
>>> ''.join('%2.2x' % ord(c) for c in s) 
'432d2000' 

यह अभी तक आप बिटवाइज़ कार्रवाई नहीं करता है, लेकिन आप तो उपयोग फिर से एक पूर्णांक में स्ट्रिंग मैप करने के लिए कर सकते हैं struct :

>>> i = struct.unpack('>l', s)[0] 
>>> print hex(i) 
0x432d2000 

और अब आप एक int जो आप बिटवाइज़ आपरेशन के किसी भी प्रकार में उपयोग कर सकते हैं (रिवर्स में एक ही दो चरणों का पालन करता है, तो बाद आपरेशन आप एक float फिर से प्राप्त करने की आवश्यकता कहा) है।

+0

उत्तर देने वाले सभी लोगों के लिए धन्यवाद। मैं काम करने के लिए दोनों तकनीकों (1 प्रकार का उपयोग कर, और 2 संरचना का उपयोग कर) प्राप्त करने में सक्षम था। जो मुझे नहीं पता वह वरीयता है। ऐसा प्रतीत होता है कि संरचना का पैक और अनपैक का उपयोग एक प्रतिनिधित्व-स्वतंत्र समाधान प्रदान करता है, लेकिन अगर मैं गलत हूं तो मुझे सही करें। – JaysonFix

+0

इसके अलावा, मैं सोच रहा था कि "ctypes" और "struct" समाधानों के बीच महत्वपूर्ण प्रदर्शन अंतर हैं या नहीं। – JaysonFix

+0

@JaysonFix: 1) क्या आपका मतलब मंच-स्वतंत्र है? यदि ऐसा है, और आप endianism के बारे में स्पष्ट हैं, मुझे लगता है कि जवाब हाँ है।2) क्या आपके लिए महत्वपूर्ण अंतर है कि आप क्या करने जा रहे हैं इस पर निर्भर करता है ... लाखों कुशलताएं? यदि ऐसा है, तो आपको अपने लिए बेंचमार्क करना चाहिए ताकि उपयोग और रखरखाव की आसानी के संदर्भ में प्रदर्शन के संदर्भ में आप दोनों प्रभावों को समझ सकें। –

0

मैं इस विषय पर बहुत अच्छी तरह से नहीं जानता हूं, लेकिन क्या आपने ctypes मॉड्यूल की कोशिश की है?

9
समस्या

है कि एक अजगर नाव वस्तु, एक आईईईई 754 नहीं हो सकता है, क्योंकि यह एक वस्तु है (वास्तव में वे कर रहे हैं, लेकिन आंतरिक रूप से वे पकड़ सकता है जो भी प्रतिनिधित्व और अधिक सुविधाजनक है) ...

लियो के रूप में है कहा, तुम ctypes के साथ एक प्रकार डाली सकते हैं, इसलिए यदि आप किसी विशेष प्रतिनिधित्व (इस मामले में, एकल परिशुद्धता) को लागू करने की जाती हैं:

from ctypes import * 
x = 173.3125 
bits = cast(pointer(c_float(x)), POINTER(c_int32)).contents.value 
print hex(bits) 
#swap the least significant bit 
bits ^= 1 

और फिर वापस:

y = cast(pointer(c_int32(bits)), POINTER(c_float)).contents.value 
2

उपयोग struct या xdrlib मॉड्यूल:

>>> import struct 
>>> x = 173.3125 
>>> rep = struct.pack('>f', x) 
>>> numeric = struct.unpack('>I', rep)[0] 
>>> '%x' %numeric 
'432d5000' 

अब आप numeric साथ काम कर सकते हैं, और फिर विपरीत दिशा में जाना अपने चल बिन्दु संख्या वापस पाने के लिए। ऋणात्मक संख्या प्राप्त करने से बचने के लिए आपको> I (हस्ताक्षरित int) का उपयोग करना होगा। xdrlib समान है।

संदर्भ: struct, xdrlib

1

संदर्भ के लिए, numpy और देखने का भी उपयोग करना संभव है।

import numpy 

def fextract(f): 
    bits = numpy.asarray(f, dtype=numpy.float64).view(numpy.int64) 
    if not bits & 0x7fffffffffffffff: # f == +/-0 
    return 0, 0 
    sign = numpy.sign(bits) 
    exponent = ((bits>>52) & 0x7ff) - 1075 
    mantissa = 0x10000000000000 | (bits & 0xfffffffffffff) 
    # from here on f == sign * mantissa * 2**exponent 
    for shift in 32, 16, 8, 4, 2, 1: 
    if not mantissa & ((1<<shift)-1): 
     mantissa >>= shift 
     exponent += shift 
    return sign * mantissa, exponent 

fextract(1.5) # --> 3, -1