2010-05-12 16 views
9

प्राप्त करने के लिए पूर्णांक को पूर्ण करने के लिए युगल कास्टिंग करें, इस तत्व को क्रमबद्ध करने के लिए तत्वों से जुड़े स्कोर हैं। यह स्कोर युगल हैं, भले ही कई उपयोगकर्ता वास्तव में पूर्णांक द्वारा क्रमबद्ध करें (उदाहरण के लिए यूनिक्स टाइम्स)।रेडिस (<a href="http://code.google.com/p/redis" rel="nofollow noreferrer">http://code.google.com/p/redis</a>) में गति

जब डेटाबेस सहेजा जाता है तो हमें यह युगल ठीक डिस्क लिखने की आवश्यकता होती है। वर्तमान में इसका उपयोग किया जाता है:

snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val); 

इसके अतिरिक्त अंतिम डेटाबेस फ़ाइल में इसका प्रतिनिधित्व करने के लिए अनंतता और संख्या-संख्या की स्थितियों की जांच भी की जाती है।

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

इसके लिए पूर्ण गति प्रदान करने के लिए पूर्णांक "समतुल्य" के लिए परीक्षण तेज होना चाहिए। इसलिए मैंने एक चाल का उपयोग किया जो शायद अनिर्धारित व्यवहार है लेकिन यह अभ्यास में बहुत अच्छा काम करता है। ऐसा ही कुछ:

double x = ... some value ... 
if (x == (double)((long long)x)) 
    use_the_fast_integer_function((long long)x); 
else 
    use_the_slow_snprintf(x); 

मेरे तर्क में डबल कास्टिंग ऊपर एक लंबे में डबल बदल देता है, और उसके बाद एक पूर्णांक में वापस। यदि सीमा फिट बैठती है, और कोई दशमलव भाग नहीं है, तो संख्या रूपांतरण में टिकेगी और प्रारंभिक संख्या के समान ही होगी।

जैसा कि मैं यह सुनिश्चित करना चाहता था कि यह कुछ सिस्टम में चीजों को तोड़ नहीं देगा, मैं freenode पर # सी में शामिल हो गया और मुझे बहुत अपमान हुआ;) तो अब मैं यहाँ कोशिश कर रहा हूं।

क्या कोई ऐसा मानक तरीका है जो मैं एएनएसआई सी के बाहर जाने के बिना करने की कोशिश कर रहा हूं? अन्यथा, उपर्युक्त कोड उन सभी पॉज़िक्स सिस्टम में काम करना चाहिए जो वर्तमान में रेडिस लक्ष्य हैं? यही वह जगह है जहां लिनक्स/मैक ओएस एक्स/* बीएसडी/सोलारिस आजकल चल रहे हैं?

कोड सेंसर बनाने के लिए मैं जो जोड़ सकता हूं, वह कास्ट की कोशिश करने से पहले डबल की सीमा के लिए एक स्पष्ट जांच है।

किसी भी मदद के लिए धन्यवाद।

+0

अपमान, आदमी के बारे में बेकार है। मुझे जवाब नहीं पता, लेकिन मुझे उम्मीद है कि आपको एक मिल जाएगा। – mmr

+0

यदि यह मदद करता है, तो http://stackoverflow.com/questions/638376/what-is-the-most-reliable-way-of-checking-if-a-floating-point-variable-is-an-inte एक था सी # में यह जांचने का तरीका। मुझे अभी तक एक सी संस्करण नहीं मिला है। –

+0

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

उत्तर

6

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

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

आपके लिए बस कुछ यादृच्छिक विचार।

+1

धन्यवाद माइकल, वाह, एफपीयू इस रूपांतरण का समर्थन करता है? यह वास्तव में एक अच्छी खबर है। इसके अलावा भागों को अलग करने और उन्हें स्वतंत्र रूप से प्रिंट करने की चाल अच्छी है। धन्यवाद यह बहुत उपयोगी है। – antirez

1

मुझे जानवरों के साथ कोई समस्या नहीं दिखाई देती है, जब तक कि एक्स लंबे समय तक सीमित न हो। शायद आपको modf() फ़ंक्शन को देखना चाहिए जो डबल को इसके अभिन्न और fractional भाग में विभाजित करता है। इसके बाद आप सुनिश्चित करने के लिए अभिन्न अंग के लिए (डबल) LLONG_MIN और (डबल) LLONG_MAX के खिलाफ चेक जोड़ सकते हैं। हालांकि डबल की परिशुद्धता के साथ कठिनाइयों हो सकती है।

लेकिन इससे कुछ करने से पहले, क्या आपने यह सुनिश्चित किया है कि यह वास्तव में इसके प्रदर्शन को मापकर एक बाधा है? और पूर्णांक मानों का प्रतिशत इतना अधिक है कि इससे वास्तव में कोई फर्क पड़ता है?

+2

आपको बहुत धन्यवाद, यह पहले ही लागू हो चुका है और कई युगल के साथ डीबी को बचाने में 2x की गति का कारण बनता है। एक प्रोफाइलिंग सत्र के बाद ऑप्टिमाइज़ेशन शुरू हुआ जहां snprintf() फ़ंक्शन बहुत धीमा दिखता था ... – antirez

2

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

यदि आप बस हैशिंग जैसी कुछ करने के लिए किसी तरह की कुंजी की तलाश में हैं, तो शायद यह ठीक काम करेगा। यदि आप वास्तव में परवाह करते हैं कि कौन से मूल्यों में वास्तव में अधिक या कम मूल्य है, तो यह एक बुरा विचार है।

+0

हां, मैंने समानता के लिए भी डबल तुलना देखी। यह समस्याओं को खोजने में मुश्किलों का स्रोत हो सकता है। यह 100 में से 99 बार काम करेगा। –

+1

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

+0

युगल की तुलना करने के बारे में पढ़ना, यह तब भी काम नहीं करता है जब संख्याएं बिल्कुल समान प्रतिनिधित्व के समान हों? मैं समझता हूं कि यदि स्ट्रिंग प्रस्तुतियों या अन्य गणित प्रसंस्करण से दो संख्याएं उत्पन्न होती हैं, तो तुलना विफल हो सकती है जबकि संख्याएं अभी भी ईपीएसलॉन-वार हैं, लेकिन मेरे विशिष्ट मामले में, मुझे समस्याओं के बिना झूठा नकारात्मक मिल सकता है, क्योंकि मैं snprintf() का उपयोग करने के सायन कोड का सहारा लेगा। यदि मैं सही ढंग से समस्या को समझता हूं तो युगल की तुलना में समस्या झूठी नकारात्मक है, झूठी सकारात्मक नहीं है। – antirez

0

आपका परीक्षण (आप पहले से ही अलग से इस बिंदु से infinities और Nans संभाला है कल्पना करते हुए) बिल्कुल ठीक है - और यह शायद बहुत कम occaisions जब तुम सच में करते समानता के लिए तैरता तुलना करना चाहते हैं में से एक है। यह अपरिभाषित व्यवहार का आह्वान नहीं करता है - भले ही xlong long की सीमा के बाहर है, तो आपको केवल "कार्यान्वयन-परिभाषित परिणाम" मिलेगा, जो ठीक है।

केवल मलहम में उड़ना यह है कि ऋणात्मक शून्य सकारात्मक शून्य के रूप में समाप्त हो जाएगा (क्योंकि नकारात्मक शून्य सकारात्मक शून्य के बराबर होता है)।

+0

धन्यवाद कैफ, मैंने इस नवीनतम घंटों में थोड़ा फ़्लोटिंग पॉइंट नंबर प्रस्तुतिकरणों का अध्ययन किया। मुझे यह भी लगता है कि यह सुरक्षित है। हां, कोड में पहले से ही नैन और इन्फिनिटी के लिए स्पष्ट जांच हैं, इसलिए सुरक्षित होना चाहिए। बस चीजों को थोड़ा सुरक्षित बनाने के लिए, मैंने #if को मंटिस और लंबे समय तक सटीक मिलान के लिए जांचने के लिए जोड़ा, इसलिए कोड को केवल संकलित किया जाता है यदि डबल में कम से कम 52 बिट सटीक होता है, तो क्रम में एक स्पष्ट परीक्षण होता है यह जांचने के लिए कि क्या डबल उस सीमा के अंदर है जहां एक लंबा लंबा ओवरफ्लो नहीं होगा (और यह परीक्षण 52 बिट रेंज में किया जाता है, इसलिए हमें गारंटी है कि यह काम करेगा)। उत्तर के लिए Thx। – antirez

+1

रेंज परीक्षण अनावश्यक है - यदि आप चाहें तो आप इसे 'char' के साथ भी कर सकते हैं। कार्यान्वयन-परिभाषित परिणाम जो आपको प्राप्त होता है जब 'डबल' सीमा से बाहर होता है, तो उसे बराबर तुलना नहीं किया जाएगा जब' डबल 'में परिवर्तित किया जाता है (सी में "अतिप्रवाह" केवल गणनाओं पर होता है, रूपांतरण नहीं)। – caf

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

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