2014-10-16 2 views
5

अक्सर, प्रोग्रामिंग भाषाओं के कार्यान्वयन के लिए, बिटटाइ ऑपरेटरों का उपयोग करके टैग संख्याओं को टैग करना वांछनीय है। सी में, आप संघ का उपयोग करके एक डबल टैग कर सकते हैं:इसके कम महत्वपूर्ण बिट का उपयोग करके जावास्क्रिप्ट पर किसी संख्या को टैग करने का शानदार तरीका?

typedef union Tag_ { double d; long long i; } Tag; 
double tag(double x){ Tag tmp; tmp.d = x; tmp.i |= 1; return tmp.d; }; 
double isTagged(double x){ Tag tmp; tmp.d = x; return tmp&1; }; 

जावास्क्रिप्ट पर इस व्यवहार की नकल करने का तरीका क्या है? बिटवाई ऑपरेटरों का उपयोग करना अस्वीकार कर दिया गया है, क्योंकि यह युगल को Uint32s में परिवर्तित करता है। मुझे गणितीय समाधान की आवश्यकता है।

+0

आप जावास्क्रिप्ट में ऐसा क्यों करना चाहते हैं? आपका वास्तविक उपयोग केस क्या है? – Bergi

+1

जावास्क्रिप्ट को एक योजना जैसी भाषा संकलित करना। कोई टैग किए गए यूनियन नहीं हैं, इसलिए अनुकरण करने के लिए डबल पर बिट्स का उपयोग करना निश्चित रूप से ऑब्जेक्ट बनाने से बहुत तेज होगा, क्योंकि यह मेरे ढेर के लिए टाइप किए गए सरणी का उपयोग करने की अनुमति देगा। – MaiaVictor

+2

मैं देखता हूं। मैं पहले से ही टाइप किए गए सरणी का उपयोग करने का प्रस्ताव देना चाहता था, क्योंकि आप * उसी * बफर पर 'Uint32Array' और 'Float64Array' का उपयोग कर सकते हैं; हालांकि मैंने सोचा कि उन तीन वस्तुओं को बनाने से "गैर-संघीय" वस्तु शब्दशः पर कोई लाभ नहीं होगा। लेकिन अगर आप उनका उपयोग कर रहे हैं ... – Bergi

उत्तर

1

इसे कोई जवाब नहीं मिला है, शायद आपको एक मिला? यदि नहीं:

मुझे अपनी टिप्पणियों में प्रश्न के साथ शुरू करने दें, क्योंकि यह अंत में उस प्रश्न को हल करने जैसा लगता है मूल प्रश्न हल करता है।

मैं एक ही सरणी के अलग-अलग दृश्य कैसे बना सकता हूं?

यह अनिवार्य रूप से Bergi's proposal टिप्पणियों से थोड़ा संशोधित है। यह कैसे का उत्तर देता है।

जब आप ArrayBuffer बनाते हैं तो आप उस सरणी बफर को प्रारंभिक पैरामीटर के रूप में पास करके एकाधिक टाइप किए गए Arrays से बाइट्स की अंतर्निहित सरणी तक पहुंच सकते हैं। मैंने JavaScripture -- ArrayBuffer को अतीत में टाइपेडअरेज़ के साथ काफी मददगार पाया है। तो निम्नलिखित स्मृति में 8 बाइट्स को सुरक्षित रखता है और इसे 64-बिट फ्लोट और 8 बाइट इंट्स दोनों के रूप में एक्सेस करता है।

var myBuff = new ArrayBuffer(8); 
var myU8Arr = new Uint8Array(myBuff); 
var myFloat64Arr = new Float64Array(myBuff); 

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

myFloat64Arr[0] = 10000; 
console.log(myFloat64Arr[0])//prints 0; 
myU8Arr[7] |= 128;//sets sign bit of IEEE 754 Double-precision float. 
//setting the sign because it's more straightforward than if another 
//bit was to be set. 
console.log(myFloat64Arr[0]);//prints -10000 ... all dependent on system endianess 

तो, अब है कि से सवाल टिप्पणियों का उत्तर दिया गया है:

मैं अपनी संख्याओं को टैग करने के लिए कम से कम महत्वपूर्ण बिट का उपयोग कैसे कर सकता हूं?

सीधे प्रश्न को संबोधित करते हुए; मुझे टाइप की गई Arrays का उपयोग करने में कोई समस्या नहीं दिख रही है। अंतर्निहित ऐरे बफर में अंतर्निहित बाइट्स पर हम बिटवाई कर सकते हैं बिना चिंता किए कि बाइट को 64-बिट फ्लोट और गड़बड़ की चीजों में बदल दिया जाएगा।

फ्लोट्स के अपने "ढेर" के साथ चिपके हुए आपको अतिरिक्त प्रदर्शन मिलेगा। सरल संख्या ArrayBuffer और फिर संख्याओं की सरणी (Tag एस की सरणी) के बजाय Uint8Array और Float64Array दोनों बनाएं। अन्यथा आप Tag फ़ंक्शन को ArrayBuffer, Uint8Array और Float64Array इसके दायरे में विशेषताओं के साथ बना सकते हैं और फिर प्रत्येक नंबर के लिए इसके नए उदाहरण बना सकते हैं ... लेकिन यह आपको जावास्क्रिप्ट क्षेत्र में कुछ भी नहीं बचाता है। tag में पॉलीफिल के साथ-साथ वैरिएबल पर विशेषता/फ़ंक्शन और संख्या प्रोटोटाइप भी हो सकता है यदि आप टैग-जैसी संरचनाओं को बनाने के उस मार्ग पर जा रहे हैं। यह आपको स्टोरेज प्रदर्शन नहीं देगा, लेकिन कम से कम टैग को प्रत्येक नंबर के साथ जोड़ देगा।

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

var globalMyBuff = new ArrayBuffer(n);//n is your number of floats * 8 (8 bytes per float) 
var globalMyU8Arr = new Uint8Array(globalMyBuff); 
var globalMyFloat64Arr = new Float64Array(globalMyBuff); 

//Load your floats into globalMyFloat64Arr 

//tag a float at index when desired 
function tag(index){ 
    //"index << 3 " is essentially the same as "index * 8", but faster 
    //since it will get compiled into a shift op 
    myU8Arr[index << 3] |= 1;//sets the LSB 
} 
//check tag at index when desired 
function isTagged(index){ 
    //"index << 3 " is essentially the same as "index * 8", but faster 
    //since it will get compiled into a shift op 
    return (myU8Arr[index << 3] & 1) == 1;//checks LSB 
} 
+1

दुर्भाग्य से, एक सरणी का उपयोग करना मेरे बेंचमार्क पर बहुत धीमा था। हालांकि, यह शायद सबसे लचीला समाधान है। मेरे विशिष्ट मामले के लिए, आईईईई 754 अंकगणित का उपयोग करके फ्लोट पर बिट्स में हेरफेर करने के लिए मेरे पास बेहतर परिणाम थे, क्योंकि जेएस तेज़ करता है। धन्यवाद! – MaiaVictor

+0

मुझे लगा कि आपने इसे पहले ही हल कर लिया है, लेकिन सवाल देखा और महसूस किया कि मुझे एक जवाब पता था :) सुनने के लिए खुशी हुई कि आपके पास समाधान था और आप अपने मामले के लिए सबसे अच्छे थे! –

+1

हाँ, मुझे पता है! आपका बहुत बहुत धन्यवाद। मैं अपना खुद का समाधान भी पोस्ट कर सकता हूं, लेकिन मैं अभी एक तंग कार्यक्रम में हूं, इसलिए उसे इंतजार करना होगा ... – MaiaVictor

संबंधित मुद्दे

 संबंधित मुद्दे