2010-08-22 17 views
12

। आधार 1 भी। जटिल प्रतिस्थापन के कुछ प्रकार।क्या मैं सी/सी ++ प्रीप्रोसेसर के साथ संख्या जोड़ सकता हूं? कुछ आधार के लिए

इसके अलावा, और यह भी, वास्तविक जीवन उत्पादन कोड में यह एक अच्छा विचार नहीं है। मैंने जिज्ञासा से पूछा।

+24

आप आधार 1 में बहुत से संख्याओं का प्रतिनिधित्व करने में सक्षम नहीं होंगे। – Artefacto

+3

हमें बेस 1 कभी नहीं छोड़ा जाना चाहिए। बिट्स बुराई हैं। –

+0

बेस 1 अतिरिक्त आसान है! मैक्रोज़/मैक्रो तर्कों को बस संयोजित करें। – alternative

उत्तर

10

आप अपेक्षाकृत आसान लिख सकते हैं मैक्रो जो बाइनरी में दो पूर्णांक जोड़ता है। उदाहरण के लिए - मैक्रो जो बाइनरी में दो 4 बिट पूर्णांकों का योग:

#include "stdio.h" 

// XOR truth table 
#define XOR_0_0 0 
#define XOR_0_1 1 
#define XOR_1_0 1 
#define XOR_1_1 0 

// OR truth table 
#define OR_0_0 0 
#define OR_0_1 1 
#define OR_1_0 1 
#define OR_1_1 1 

// AND truth table 
#define AND_0_0 0 
#define AND_0_1 0 
#define AND_1_0 0 
#define AND_1_1 1 

// concatenation macros 
#define XOR_X(x,y) XOR_##x##_##y 
#define OR_X(x,y) OR_##x##_##y 
#define AND_X(x,y) AND_##x##_##y 
#define OVERFLOW_X(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) OVERFLOW_##rc1 (rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) 

// stringification macros 
#define STR_X(x) #x 
#define STR(x) STR_X(x) 

// boolean operators 
#define XOR(x,y) XOR_X(x,y) 
#define OR(x,y) OR_X(x,y) 
#define AND(x,y) AND_X(x,y) 

// carry_bit + bit1 + bit2 
#define BIT_SUM(carry,bit1,bit2) XOR(carry, XOR(bit1,bit2)) 
// carry_bit + carry_bit_of(bit1 + bit2) 
#define CARRY_SUM(carry,bit1,bit2) OR(carry, AND(bit1,bit2)) 

// do we have overflow or maybe result perfectly fits into 4 bits ? 
#define OVERFLOW_0(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) SHOW_RESULT(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) 
#define OVERFLOW_1(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) SHOW_OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) 

// draft-horse macros which performs addition of two 4-bit integers 
#define ADD_BIN_NUM(a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_4(0,0,0,0, 0,0,0,0, a1,a2,a3,a4, b1,b2,b3,b4) 
#define ADD_BIN_NUM_4(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_3(rc1,rc2,rc3,AND(CARRY_SUM(0,a4,b4),OR(a4,b4)), rb1,rb2,rb3,BIT_SUM(0,a4,b4), a1,a2,a3,a4, b1,b2,b3,b4) 
#define ADD_BIN_NUM_3(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_2(rc1,rc2,AND(CARRY_SUM(rc4,a3,b3),OR(a3,b3)),rc4, rb1,rb2,BIT_SUM(rc4,a3,b3),rb4, a1,a2,a3,a4, b1,b2,b3,b4) 
#define ADD_BIN_NUM_2(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_1(rc1,AND(CARRY_SUM(rc3,a2,b2),OR(a2,b2)),rc3,rc4, rb1,BIT_SUM(rc3,a2,b2),rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) 
#define ADD_BIN_NUM_1(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)  OVERFLOW(AND(CARRY_SUM(rc2,a1,b1),OR(a1,b1)),rc2,rc3,rc4, BIT_SUM(rc2,a1,b1),rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) 
#define OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) OVERFLOW_X(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) 
#define SHOW_RESULT(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) STR(a1) STR(a2) STR(a3) STR(a4) " + " STR(b1) STR(b2) STR(b3) STR(b4) " = " STR(rb1) STR(rb2) STR(rb3) STR(rb4) 
#define SHOW_OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) STR(a1) STR(a2) STR(a3) STR(a4) " + " STR(b1) STR(b2) STR(b3) STR(b4) " = overflow" 

void main() 
{ 
    printf("%s\n", 
     ADD_BIN_NUM(
        0,0,0,1, // first 4-bit int 
        1,0,1,1) // second 4-bit int 
        ); 

    printf("%s\n", 
     ADD_BIN_NUM(
        0,1,0,0, // first 4-bit int 
        0,1,0,1) // second 4-bit int 
       ); 

    printf("%s\n", 
     ADD_BIN_NUM(
        1,0,1,1, // first 4-bit int 
        0,1,1,0) // second 4-bit int 
       ); 
} 

इस मैक्रो आसानी से दो 8 बिट या 16-बिट या यहाँ तक कि 32-बिट ints के अलावा के लिए बढ़ाया जा सकता है। तो मूल रूप से मैक्रोज़ के साथ अद्भुत परिणाम प्राप्त करने के लिए हमें जो कुछ चाहिए वह टोकन कॉन्सटेनेशन और प्रतिस्थापन नियम है।

संपादित करें: मैंने परिणामों का गठन बदल दिया है और अधिक महत्वपूर्ण बात - मैंने ओवरफ्लो चेक जोड़ा है।

एचटीएच!

0

मुझे पूरा यकीन है कि सी/सी ++ प्रीप्रोसेसर सिर्फ कॉपी और पेस्ट करता है - यह वास्तव में किसी भी अभिव्यक्ति का मूल्यांकन नहीं करता है। अभिव्यक्ति मूल्यांकन संकलक द्वारा किया जाता है।

अपने प्रश्न का बेहतर उत्तर देने के लिए, आप जो भी पूरा करने की कोशिश कर रहे हैं उसे पोस्ट करना चाहेंगे।

+6

प्रीप्रोसेसर कुछ अभिव्यक्ति मूल्यांकन करता है। '# If' और' elif' निर्देश दोनों अभिव्यक्ति लेते हैं जिन्हें मैक्रो प्रतिस्थापित किया जाना चाहिए और फिर यह निर्धारित करने के लिए मूल्यांकन किया जाता है कि वे सही या गलत (या एक या शून्य, सी में) का मूल्यांकन करते हैं या नहीं। –

5

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

#include <iostream> 
using namespace std; 

template <int N, int M> 
struct Add 
{ 
    static const int Value = N + M; 
}; 

int main() 
{ 
    cout << Add<4, 5>::Value << endl; 
    return 0; 
} 
+2

क्यों 'एड' के अंदर 'मूल्य = एन + एम' का उपयोग न करें? –

+0

@ जेम्स: महान बिंदु, धन्यवाद। मैंने अपनी प्रतिक्रिया अपडेट की है। –

12

पूर्वप्रक्रमक preprocessing टोकन पर चल रही है और केवल समय है कि यह संख्या का मूल्यांकन करता है एक #if या #elif निर्देश के मूल्यांकन के दौरान होता है। इसके अलावा, पूर्व प्रसंस्करण के दौरान संख्या वास्तव में संख्या नहीं है; उन्हें प्रीप्रोकैसिंग संख्या टोकन के रूप में वर्गीकृत किया गया है, जो वास्तव में संख्याएं नहीं हैं।

आप टोकन संयोजन का उपयोग कर बुनियादी अंकगणितीय का मूल्यांकन कर सकते हैं:

#define ADD_0_0 0 
#define ADD_0_1 1 
#define ADD_1_0 1 
#define ADD_1_1 2 

#define ADD(x, y) ADD##_##x##_##y 

ADD(1, 0) // expands to 1 
ADD(1, 1) // expands to 2 

वास्तव में, हालांकि, वहाँ यह करने के लिए कोई कारण नहीं है, और यह ऐसा करने के लिए मूर्खतापूर्ण होगा (आप की एक बड़ी संख्या को परिभाषित करना होगा इसके लिए मैक्रोज़ भी दूरस्थ रूप से उपयोगी होने के लिए)।

#define ADD(x, y) ((x) + (y)) 

ADD(1, 1) // expands to ((1) + (1)) 

संकलक 1 + 1 अभिव्यक्ति का मूल्यांकन करने में सक्षम हो जाएगा:

यह एक ऐसा मैक्रो अभिन्न निरंतर अभिव्यक्ति है कि संकलक द्वारा मूल्यांकन किया जा सकता करने के लिए फैलता है करने के लिए और अधिक समझदार हो जाएगा।

+2

मैं हमेशा कुछ वास्तविक काम करने के लिए ## देखना पसंद करता हूं। – Tom

1

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

1

प्रीप्रोसेसर मैक्रोज़ वास्तव में अंकगणित नहीं कर सकते हैं, लेकिन गणित करने के लिए उन्हें गणित करने के लिए उपयोगी रूप से लीवरेज किया जा सकता है। सामान्य चाल एक मैक्रो है जो अन्य मैक्रोज़ को आमंत्रित करती है, और उन अन्य मैक्रोज़ की विभिन्न परिभाषाओं का उपयोग करके बार-बार बुलाया जा सकता है।

उदाहरण के लिए, कुछ की तरह:

 
#define MY_THINGS \ 
    a_thing(FRED,4) \ 
    a_thing(GEORGE,6) \ 
    a_thing(HARRY,5) \ 
    a_thing(HERMIONE,8) \ 
    a_thing(RON,3) \ 
    // This line left blank 

#define a_thing(name,size) EN_##name}; enum {EN_SIZE_##name=(size),EN_BLAH_##name = EN_##name+(size-1), 
enum {EN_FIRST_THING=0, MY_THINGS EN_TOTAL_SIZE}; 
#undef a_thing 

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

3

स्पष्ट रूप से, आप कर सकते हैं। यदि आप Boost Preprocessor लाइब्रेरी पर एक नज़र डालें, तो आप प्रीप्रोसेसर के साथ सभी प्रकार की चीजें कर सकते हैं, यहां तक ​​कि पूर्णांक addition भी कर सकते हैं।

+0

बूस्ट प्रीप्रोसेसर ने (पिछली बार मैंने जांच की थी, कुछ साल पहले) spec के साथ खराब अनुपालन।अतिरिक्त बिट बिल्कुल कल्पना में नहीं है। – EML

+1

@EML - मैं बूस्ट वेव लाइब्रेरी के बारे में बात नहीं कर रहा हूं, जो एक सी/सी ++ प्री-प्रोसेसर का कार्यान्वयन है जिसे आप अपने कोड में उपयोग कर सकते हैं, बल्कि बूस्ट प्रीप्रोसेसर लाइब्रेरी, जो पहले से ही आपके प्रीपेसेसर का उपयोग करता है सी/सी ++ कंपाइलर कुछ अद्भुत चीजें करने के लिए। – Ferruccio

5

प्रीप्रोसेसर में बाध्य पूर्णांक अतिरिक्त करना संभव है। और, वास्तव में वास्तव में उम्मीद की जाती है कि वास्तव में उम्मीद की जायेगी, यानी, कार्यक्रम में केवल ((2) + (3)) का विकल्प काम नहीं करता है। (उदा।, आपके पास x((2)+(3)) नामक एक चर नहीं हो सकता है)। विचार सरल है: वृद्धि को बढ़ाने के लिए बारी करें, जिसे आप ध्यान में रखते हैं (बहुत अधिक) उन्हें सभी को सूचीबद्ध करते हैं। जैसे,

#define INC(x) INC_ ## x 
#define INC_0 1 
#define INC_1 2 
#define INC_2 3 
#define INC_3 4 
#define INC_4 5 
#define INC_5 6 
#define INC_6 7 
#define INC_7 8 
#define INC_8 9 
#define INC_9 10 
INC(7) // => 8 

अब हम कैसे अप करने के लिए 1.

#define ADD(x, y) ADD_ ## x(y) 
#define ADD_0(x) x 
#define ADD_1(x) INC(x) 
ADD(0, 2) // => 2 
ADD(1, 2) // => 3 

को भी बड़ी संख्या में जोड़ने के लिए करने के अलावा करने के लिए पता है, तुम "प्रत्यावर्तन" के कुछ प्रकार की जरूरत है।

#define ADD_2(x) ADD_1(INC(x)) 
#define ADD_3(x) ADD_2(INC(x)) 
#define ADD_4(x) ADD_3(INC(x)) 
#define ADD_5(x) ADD_4(INC(x)) 
#define ADD_6(x) ADD_5(INC(x)) 
#define ADD_7(x) ADD_6(INC(x)) 
#define ADD_8(x) ADD_7(INC(x)) 
#define ADD_9(x) ADD_8(INC(x)) 
#define ADD_10(x) ADD_9(INC(x)) 
ADD(5, 2) // => 7 

हालांकि, इसमें किसी को सावधान रहना होगा। उदा।, निम्नलिखित काम नहीं करता है।

#define ADD_2(x) INC(ADD_1(x)) 
ADD(2, 2) // => INC_ADD_1(2) 

ऐसी चालों के किसी भी विस्तारित उपयोग के लिए, बूस्ट प्रीप्रोसेसर आपका मित्र है।

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

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