2008-08-29 7 views
5

कुछ कोड है कि प्रदर्शन करने के लिए विभाजन अप राउंड (सी-वाक्य रचना):लिनक्स कर्नेल में दो 64-बिट संख्याओं को विभाजित करने के लिए कैसे?

#define SINT64 long long int 
#define SINT32 long int 

SINT64 divRound(SINT64 dividend, SINT64 divisor) 
{ 
    SINT32 quotient1 = dividend/divisor; 

    SINT32 modResult = dividend % divisor; 
    SINT32 multResult = modResult * 2; 
    SINT32 quotient2 = multResult/divisor; 

    SINT64 result = quotient1 + quotient2; 

    return (result); 
} 

अब, अगर यह उपयोगकर्ता-अंतरिक्ष थे हम शायद पता ही नहीं चलता है कि हमारे संकलक उन ऑपरेटरों के लिए कोड पैदा कर रहा है (उदाहरण के लिए विभाजन के लिए divdi3())। संभावना है कि हम इसे 'libgcc' के साथ भी जानते हुए बिना लिंक कर रहे हैं। समस्या यह है कि कर्नेल-स्पेस अलग है (उदा। कोई libgcc नहीं)। क्या करें?

थोड़ी देर के लिए

क्रॉल गूगल, सूचना है कि काफी हर किसी अहस्ताक्षरित संस्करण पते:

#define UINT64 long long int 
#define UINT32 long int 

UINT64 divRound(UINT64 dividend, UINT64 divisor) 
{ 
    UINT32 quotient1 = dividend/divisor; 

    UINT32 modResult = dividend % divisor; 
    UINT32 multResult = modResult * 2; 
    UINT32 quotient2 = multResult/divisor; 

    UINT64 result = quotient1 + quotient2; 

    return (result); 
} 

मुझे पता है कि यह एक ठीक करने के लिए: ओवरराइड udivdi3() और umoddi3() _do_div साथ () _ एएसएम/div64.h से। सही किया? गलत। हस्ताक्षरित हस्ताक्षर के समान नहीं है, sdivdi3() _ udivdi3() पर कॉल नहीं करता है, वे एक कारण के लिए अलग-अलग कार्य हैं।

क्या आपने इस समस्या को हल किया है? क्या आप एक पुस्तकालय के बारे में जानते हैं जो मुझे ऐसा करने में मदद करेगा? मैं वास्तव में अटक गया हूं, जो भी आप यहां देख सकते हैं कि मैं अभी ठीक नहीं हूं, वास्तव में सहायक होगा।

धन्यवाद, चाड

उत्तर

0

ldiv?

संपादित करें: शीर्षक पढ़ें, ताकि आप इसे अनदेखा कर सकें। या नहीं, इस पर निर्भर करता है कि उसके पास उचित गैर-पुस्तकालय संस्करण है या नहीं।

4

यहां मेरा वास्तव में बेवकूफ समाधान है। आपकी माइलेज भिन्न हो सकती है।

एक साइन बिट रखें, जो sign(dividend)^sign(divisor) है। (या *, या /, आप के रूप में झूठे और सच। असल में, नकारात्मक करने का विरोध करता है, तो या तो एक, नकारात्मक सकारात्मक है अगर कोई भी या दोनों नकारात्मक हैं 1 और -1 के रूप में अपने हस्ताक्षर,। भंडारण कर रहे हैं)

फिर , दोनों के पूर्ण मूल्यों पर हस्ताक्षरित विभाजन समारोह को कॉल करें। फिर परिणाम पर वापस साइन इन करें।

पीएस वास्तव में __divdi3libgcc2.c (जीसीसी 4.2.3 से, संस्करण जो मेरे उबंटू सिस्टम पर स्थापित है) में लागू किया गया है। मैंने अभी जाँच की। :-)

0

मुझे नहीं लगता कि इस मामले में Chris' answer काम क्योंकि do_div() वास्तव में यथा-स्थान लाभांश बदल जाता है (कम से कम करने के लिए एक तरह से नहीं मिल सकता है)। पूर्ण मूल्य प्राप्त करना एक अस्थायी चर का तात्पर्य है जिसका मूल्य मुझे आवश्यक तरीके से बदल देगा लेकिन मेरे __divdi3() ओवरराइड से बाहर नहीं किया जा सकता है।

मैं छोड़कर do_div() द्वारा प्रयोग किया जाता तकनीक की नकल करने के इस बिंदु पर पैरामीटर-दर-मूल्य __divdi3() के हस्ताक्षर के चारों ओर एक रास्ता नहीं दिख रहा।

ऐसा लगता है कि मैं यहां पीछे झुक रहा हूं और मुझे वास्तव में 64-बिट/32-बिट डिवीजन करने के लिए एल्गोरिदम के साथ आना चाहिए। यहां जोड़ा गया जटिलता यह है कि मेरे पास '/' ऑपरेटर का उपयोग करके संख्यात्मक कोड का एक समूह है और उसे उस कोड के माध्यम से जाना होगा और प्रत्येक '/' को मेरे फ़ंक्शन कॉल के साथ प्रतिस्थापित करना होगा।

मैं बस इतना करने के लिए काफी हताश हो रहा हूं।

किसी भी अनुवर्ती के लिए धन्यवाद, चाड

2

यह कार्यक्षमता के रूप में जल्दी गिरी v2.6.22 के रूप में /linux/lib/div64.c में शुरू की है।

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