2012-07-18 15 views
5

मैं वर्तमान में जावा के लिए सी से कुछ OpenCV कोड परिवर्तित कर रहा हूँ ++। मैं JavaCV का उपयोग नहीं कर सकता, क्योंकि हमें मूल जावा में रूपांतरण की आवश्यकता है, न कि जेएनए।यूनरी माइनस ऑपरेटर सी ++ में बूलियन पर कैसे काम करता है?

dst[x] = (uchar)(-(kHit >= kForeground)); 

कहाँ dstuchar*, kHit और kForeground है int रों हैं: कोड में एक बिंदु पर, मैं निम्नलिखित काम मिलता है।

मैं यह कैसे काम करता बारे में कुछ भी खोजने में असमर्थ किया गया है, और जावा एक ऑपरेशन के रूप में मान्यता नहीं दी जाएगी। कोड में किसी अन्य बिंदु पर इन दो चरों पर एक ऑपरेशन है, और यह दो मानों में से एक को स्टोर करता है: 255 या 0.

प्रश्न में कोड opencv/video/src/bgfg_gaussmix.cpp से आता है।

उत्तर

7

सी ++ में एक बूलियन अभिव्यक्ति दो मानों में से एक - 0 या 1 उत्पन्न करती है। जब आप परिणाम के लिए एकल शून्य से - लागू होते हैं, आप 0 या -1 मिलता है। जब आप फिर से व्याख्या -1uchar के रूप में, आप 255 मिलता है। क्योंकि शाखाओं में, यह के रूप में तेजी से मूल एक के रूप में होने के लिए नहीं जा रहा है की

dst[x] = (kHit >= kForeground) ? 255 : 0; 

:

आप एक सशर्त साथ जावा को यह अभिव्यक्ति बदल सकते हैं। हालांकि, आप इसकी गति के बारे में बहुत कुछ कर सकते हैं, हालांकि, जावा में बूलियन मानों को संख्यात्मक के रूप में दोबारा समझने की क्षमताओं की कमी है।

+0

यह समझ में आता है, और ऐसा कुछ है जिसे मैं आसानी से परीक्षण और खोज सकता था। संक्षेप में इसे इंगित करने के लिए धन्यवाद। – Wraith967

+0

तकनीकी रूप से बूलियन अभिव्यक्ति या तो 'सत्य' या 'झूठी' उत्पन्न करती है, जब किसी 'int' को पदोन्नत किया जाता है तो मान '1' या' 0' प्राप्त होंगे। –

6

kHit >= kForeground रिटर्न या तो true या false, C++ एक तरह से है जिसका अर्थ है 1 या 0। सामने के शून्य से यह -1 या 0 में बदल जाता है। uchar ((uchar)) के लिए 00 के लिए पर नकारात्मक -1 के लिए 0 लौटाता है।

कोनराड की टिप्पणी के बाद, मैं भी यह अच्छी तरह से परिभाषित किया गया है उलझन में हूँ। यह अच्छी तरह से परिभाषित है, लेकिन यह अभी भी पठनीयता के मामले में कोड का एक भयानक टुकड़ा है। :)

+3

* कुछ * कंपाइलर/मशीन पर। यह कोड अनावश्यक रूप से अप्राप्य है। –

+2

क्या सी ++ मानक स्पष्ट रूप से बिना हस्ताक्षर किए गए प्रकारों को दो-पूरक के रूप में व्यवहार करने के लिए निर्दिष्ट करता है, इसलिए यह अच्छी तरह से परिभाषित किया जाना चाहिए (जैसा कि सही == 1 और झूठा == 0 अच्छी तरह परिभाषित भी है)? –

+0

@ कोनराड रुडॉल्फ: मानक निर्दिष्ट करता है कि 'प्रकार के बूल का एक प्रकार टाइप int के प्रसार में परिवर्तित किया जा सकता है, झूठ शून्य हो रहा है और सच हो रहा है।' [Conv.prom], और 'यदि गंतव्य प्रकार हस्ताक्षरित है, परिणामस्वरूप मान स्रोत पूर्णांक के अनुरूप कम से कम हस्ताक्षरित पूर्णांक है (मॉड्यूल 2 एन जहां एन हस्ताक्षरित प्रकार का प्रतिनिधित्व करने के लिए उपयोग की जाने वाली बिट्स की संख्या है) '[conv.integral]। तो मुझे लगता है कि यह कोड वास्तव में अच्छी तरह से परिभाषित और अनुपालन संकलक में पोर्टेबल है। –

1

क्या यह मूल रूप से करता है निम्नलिखित है:

kHit >= kForeground 

प्रकार bool की अभिव्यक्ति

-(kHit >= kForeground) 

किसी पूर्णांक (true==1 और false==0 के आधार पर) में इस bool परिवर्तित करता है और यह नकारता है, जो परिणाम true==-1 और false==0 में।

इसे फिर uchar में परिवर्तित किया गया है, जिसके परिणामस्वरूप -1==255 और 0==0 है।

यह ध्यान दिया जाना चाहिए कि संख्याओं के अंतर्निहित कार्यान्वयन विवरण का उपयोग करने के रूप में प्रतीत होता है, फिर भी उन सभी रूपांतरणों को सी ++ और सी मानकों द्वारा गारंटी दी जाती है, क्योंकि ऋणात्मक हस्ताक्षरित संख्याओं को दोहरे पूरक के अनुसार व्यवहार करने के लिए निर्दिष्ट किया जाता है।

लेकिन अगर जावा इस का समर्थन नहीं करता, तो आप हमेशा यह एक सशर्त असाइनमेंट द्वारा जगह ले सकता है:

dst[x] = (kHit>=kForeground) ? 255 : 0; 
1

अभिव्यक्ति (kHit >= kForeground) एक बूलियन मान true या false है कि अर्जित करता है। जब एकल - लागू किया जाता है, bool एक int के लिए प्रोत्साहित किया जाता है, और रूपांतरण true या 0false के लिए के लिए 1 अर्जित करता है। पदोन्नति के बाद, संकेत -1 या 0 में बदल दिया गया है और फिर इसे बाहरी कास्ट द्वारा uchar में परिवर्तित कर दिया गया है।

ध्यान दें कि जानकारी का महत्वपूर्ण हिस्सा यह है कि यूनरी operator- एक बूलियन पर लागू नहीं होता है, लेकिन बूलियन int में परिवर्तित हो जाता है और फिर इसे लागू किया जाता है। यही कारण है कि टेम्पलेट जादू का एक सा के साथ परीक्षण किया जा सकता है:

template <typename T, typename U> 
struct same_type { 
    static const bool value = false; 
}; 
template <typename T> 
struct same_type<T,T> { 
    static const bool value = true; 
}; 
template <typename T> 
void f(T value) { 
    std::cout << "Is int? " << std::boolalpha << same_type<T, int>::value << "\n"; 
    std::cout << "Is bool? " << same_type<T, bool>::value << "\n"; 
} 
int main() { 
    f(-true); 
} 

f टेम्पलेट ऊपर same_type टेम्पलेट्स (पर्याप्त तुच्छ समझने के लिए) का उपयोग करके int और bool के खिलाफ पारित कर दिया तर्क के प्रकार के परीक्षण करती है। अगर हम f टेम्पलेट को -true पर कॉल करते हैं तो तर्क प्रकार की कटौती T को -true अभिव्यक्ति के प्रकार के रूप में सेट करेगी। यदि आप प्रोग्राम चलाते हैं, तो आप देखेंगे कि यह Is int? true\nIs bool? false प्रिंट करता है।

+0

अच्छा जवाब, लेकिन मुझे लगता है कि आप दो बुनियादी अधिभारों के साथ अभिन्न रूपांतरण का स्पष्ट रूप से स्पष्ट कर सकते हैं। 'शून्य एफ (int) {cout <<" int \ n "; } शून्य एफ (बूल) {cout << "बूल \ n"; } एफ (सच); एफ (-true); ' –

+0

@LucTouraille: मुझे लगता है, मेरे पास बस [हथौड़ा] (http://en.wikipedia.org/wiki/Law_of_the_instrument) मेरे टूलबॉक्स में था (अब मुझे लगता है कि इसमें एक सरल है दृष्टिकोण: 'टेम्पलेट शून्य प्रिंट_टाइप (टी); print_type (-true);' ('print_type' घोषित, परिभाषित नहीं किया गया) आपको लिंकर संदेश में टाइप बताएगा –