2009-10-20 24 views
8

मान लीजिए कि मेरे पास हेक्स नंबर "4072508200000000" है और मुझे लगता है कि यह आईईईई -754 डबल प्रारूप में फ़्लोटिंग पॉइंट नंबर (2 9 3.03173828125000) का प्रतिनिधित्व करता है एक जावास्क्रिप्ट चर में डाल दिया।एक आईईईई -754 डबल के हेक्स प्रस्तुति के साथ एक स्ट्रिंग को जावास्क्रिप्ट न्यूमेरिक वेरिएबल

मैं ऐसे तरीके से सोच सकता हूं जो कुछ मास्किंग और कॉल() को कॉल करने के लिए उपयोग करता है, लेकिन क्या कोई आसान समाधान है?

क्लाइंट-साइड समाधान की आवश्यकता है।

इससे मदद मिल सकती है। यह एक ऐसी वेबसाइट है जो आपको आईईईई -754 के हेक्स एन्कोडिंग में प्रवेश करने देती है और मंटिसा और एक्सपोनेंट का विश्लेषण प्राप्त करती है।

http://babbage.cs.qc.edu/IEEE-754/64bit.html

क्योंकि लोगों को हमेशा पूछने के लिए "क्यों ?," यहाँ है करते हैं क्यों: मैं गूगल के Procol बफ़र (Protobuf) के एक मौजूदा लेकिन अधूरा कार्यान्वयन को भरने के लिए कोशिश कर रहा हूँ।

+0

व्यक्तिगत रूप से मैं हेक्स वैल्यू को अलग-अलग टुकड़ों में रेगेक्स के साथ चिपकाने से शुरू करूंगा। फिर, मैं उनको पूर्णांक के रूप में मूल्यांकन करूंगा, और अंत में मैं उन्हें वापस एक फ्लोट में बदलने की कोशिश करता हूं। ऐसा कुछ ऐसा लगता है जो मुश्किल हो रहा है, क्योंकि आपको ऐसा करने की ज़रूरत है कि जावास्क्रिप्ट रनटाइम रास्ते में किसी भी बिट को खो नहीं देता है। – Pointy

+0

अधिकतम पोर्टेबिलिटी के लिए, आपको यह समझना चाहिए कि आईईईई -754 युगल या तो बड़े-एंडियन या छोटे-एंडियन हो सकते हैं। यदि आप जानते हैं कि हेक्स इनपुट द्वारा कौन सा सम्मेलन उपयोग किया जाता है, तो पाउ() का उपयोग कर क्लाइंट-साइड समाधान पोर्टेबल होना चाहिए। यदि आप किसी प्रकार के टाइप-पनिंग दृष्टिकोण का उपयोग करने का निर्णय लेते हैं, तो डबल्स के लिए क्लाइंट प्लेटफॉर्म उन्मूलन को पहले जांचना होगा। –

+0

@ जिम लेविस: मेरे पास एक ध्वज है जो मुझे बड़ा या छोटा एंडियन बताता है। – Nosredna

उत्तर

10

मुझे एक अच्छा तरीका पता नहीं है। यह निश्चित रूप से मुश्किल तरीके से किया जा सकता है, यहाँ एक एकल परिशुद्धता उदाहरण पूरी तरह से जावास्क्रिप्ट के भीतर है:

js> a = 0x41973333 
1100428083 
js> (a & 0x7fffff | 0x800000) * 1.0/Math.pow(2,23) * Math.pow(2, ((a>>23 & 0xff) - 127)) 
18.899999618530273 

एक उत्पादन कार्यान्वयन पर विचार करना चाहिए कि खेतों के अधिकांश, जादू मान आम तौर पर के लिए एक विशेष व्याख्या निर्दिष्ट करने के द्वारा लागू किया क्या सबसे बड़ा या छोटा होता। तो, NaN एस और infinities का पता लगाएं। उपर्युक्त उदाहरण नकारात्मकों की जांच करनी चाहिए। (& 0x80000000)

अपडेट: ठीक है, मुझे इसे डबल के लिए भी मिला है। आप सीधे उपर्युक्त तकनीक का विस्तार नहीं कर सकते क्योंकि आंतरिक जेएस प्रतिनिधित्व एक डबल है, और इसलिए इसकी परिभाषा के अनुसार यह लंबाई 52 की सबसे अच्छी स्ट्रिंग पर संभाल सकता है, और यह 32 से अधिक नहीं हो सकता है।

ठीक है, आप दो बार करने के लिए पहले को स्ट्रिंग कम 8 अंकों या 32 बिट्स के रूप में काट लें; उन्हें एक अलग वस्तु के साथ संसाधित करें। फिर:

js> a = 0x40725082  
1081233538 
js> (a & 0xfffff | 0x100000) * 1.0/Math.pow(2, 52 - 32) * Math.pow(2, ((a >> 52 - 32 & 0x7ff) - 1023)) 
293.03173828125 
js> 

मैंने उपर्युक्त उदाहरण रखा क्योंकि यह ओपी से है। एक कठिन मामला तब होता है जब कम 32-बिट्स का मूल्य होता है।

js> a = 0x40725082 
1081233538 
js> b = 0xdeadbeef 
3735928559 
js> e = (a >> 52 - 32 & 0x7ff) - 1023 
8 
js> (a & 0xfffff | 0x100000) * 1.0/Math.pow(2,52-32) * Math.pow(2, e) +   
    b * 1.0/Math.pow(2, 52) * Math.pow(2, e) 
293.0319506442019 
js> 

कुछ स्पष्ट subexpressions आप को अलग कर सकते हैं लेकिन मैं इसे इस तरह से छोड़ दिया है ताकि आप देख सकते हैं कि यह कैसे प्रारूप से संबंधित है: यहाँ 0x40725082deadbeef का रूपांतरण है, एक पूर्ण परिशुद्धता डबल है।

+0

मेरा आखिरी उदाहरण 0x40725082deadbeef के लिए आपकी लिंक की गई साइट से सहमत है। – DigitalRoss

+0

बहुत अच्छा। धन्यवाद। – Nosredna

+0

यह कोड (सेकेंडलास्ट उदाहरण) '1.1125369292536007e-308' क्यों देता है जब एक = 0? – etuardu

4

डिजिटलरॉस समाधान के लिए एक त्वरित जोड़ा, जो Google के द्वारा इस पृष्ठ को ढूंढने वालों के लिए मैंने किया था।

s = a >> 31 ? -1 : 1 

फिर आप शामिल कर सकते हैं s:

के लिए +/- इन्फिनिटी और NaN बढ़त मामलों, जो मैं पर इनपुट अच्छा लगेगा से

अलावा, आप को भी ध्यान में परिणाम के हस्ताक्षर लेने की जरूरत सही परिणाम प्राप्त करने के लिए अंतिम गुणा में।

मुझे लगता है कि एक छोटे-एंडियन समाधान के लिए आपको a और b में बिट्स को रिवर्स करने की आवश्यकता होगी और उन्हें स्वैप करें।

1

नई Typed Arrays तंत्र आपको ऐसा करने की अनुमति देता है (और शायद प्रोटोकॉल बफ़र्स को लागू करने के लिए एक आदर्श व्यवस्था है):

var buffer = new ArrayBuffer(8); 
var bytes = new Uint8Array(buffer); 
var doubles = new Float64Array(buffer); // not supported in Chrome 

bytes[7] = 0x40; // Load the hex string "40 72 50 82 00 00 00 00" 
bytes[6] = 0x72; 
bytes[5] = 0x50; 
bytes[4] = 0x82; 
bytes[3] = 0x00; 
bytes[2] = 0x00; 
bytes[1] = 0x00; 
bytes[0] = 0x00; 

my_double = doubles[0]; 

document.write(my_double); // 293.03173828125 

यह एक छोटे-endian मशीन मान लिया गया है।

दुर्भाग्यवश क्रोम में Float64Array नहीं है, हालांकि इसमें Float32Array है। उपर्युक्त उदाहरण फ़ायरफ़ॉक्स 4.0.1 में काम करता है।