low level - + ऑपरेटर का उपयोग किए बिना दो नंबर जोड़ने का सबसे अच्छा तरीका क्या है?




low-level addition (12)

कारण ADD एक एकल निर्देश के रूप में कोडांतरक में लागू होता है, बजाय bitwise कार्यों के कुछ संयोजन के रूप में, यह करना कठिन है आपको अगले उच्च ऑर्डर बिट के लिए दिए गए कम ऑर्डर बिट के बारे में चिंता करने की ज़रूरत है ये चीजें हैं जो मशीनों को हार्डवेयर में तेजी से करते हैं, लेकिन यह भी कि सी के साथ, आप सॉफ्टवेयर में तेजी से नहीं कर सकते

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


क्यों न सिर्फ पहली संख्या को लगातार दूसरे नंबर के रूप में बढ़ाया जाए?


ध्यान दें, यह एक स्पीपल-लेयर योजक के रूप में जाना जाता है, जो काम करता है, लेकिन बेहतर प्रदर्शन नहीं करता है। हार्डवेयर में निर्मित अधिकांश बाइनरी एडेटर तेजी से योजक का एक रूप है जैसे लेयर-लुक-अग्रे योजक

यदि आप carry_in को 0 पर सेट करते हैं, और लेयर_इन 1 पर सेट होते हैं, तो मेरा लहर-लेयर योजक अहस्ताक्षरित और 2 के पूरक पूर्णांक दोनों के लिए काम करता है। इसके अलावा मैंने इसके अलावा अंडरफ्लो या अतिप्रवाह दिखाने के लिए झंडे जोड़े।

#define BIT_LEN 32
#define ADD_OK 0
#define ADD_UNDERFLOW 1
#define ADD_OVERFLOW 2

int ripple_add(int a, int b, char carry_in, char* flags) {
    int result = 0;
    int current_bit_position = 0;
    char a_bit = 0, b_bit = 0, result_bit = 0;

    while ((a || b) && current_bit_position < BIT_LEN) {
        a_bit = a & 1;
        b_bit = b & 1;
        result_bit = (a_bit ^ b_bit ^ carry_in);
        result |= result_bit << current_bit_position++;
        carry_in = (a_bit & b_bit) | (a_bit & carry_in) | (b_bit & carry_in);
        a >>= 1;
        b >>= 1;
    }

    if (current_bit_position < BIT_LEN) {
        *flags = ADD_OK;
    }
    else if (a_bit & b_bit & ~result_bit) {
        *flags = ADD_UNDERFLOW;
    }
    else if (~a_bit & ~b_bit & result_bit) {
        *flags = ADD_OVERFLOW;
    }
    else {
        *flags = ADD_OK;
    }

    return result;
}

नहीं + सही है?

int add(int a, int b) 
{
   return -(-a) - (-b);
}

int add(int a, int b) {
   const char *c=0;
   return &(&c[a])[b];
}

आप इसे बिट-स्थानांतरण और एंड ऑपरेशन का उपयोग करके कर सकते हैं।

#include <stdio.h>

int main()
{
    unsigned int x = 3, y = 1, sum, carry;
    sum = x ^ y; // Ex - OR x and y
    carry = x & y; // AND x and y
    while (carry != 0) {
        carry = carry << 1; // left shift the carry
        x = sum; // initialize x as sum
        y = carry; // initialize y as carry
        sum = x ^ y; // sum is calculated
        carry = x & y; /* carry is calculated, the loop condition is
                        evaluated and the process is repeated until
                        carry is equal to 0.
                        */
    }
    printf("%d\n", sum); // the program will print 4
    return 0;
}

"सर्वश्रेष्ठ" को परिभाषित करें यहां एक अजगर संस्करण है:

len(range(x)+range(y))

+ सूची समापन का कार्य करता है, इसके अतिरिक्त नहीं।


मैंने इसे कोडिंग साक्षात्कार में समस्या 18.1 के रूप में देखा। मेरा पायथन समाधान:

def foo(a, b):
"""iterate through a and b, count iteration via a list, check len"""
    x = []
    for i in range(a):
            x.append(a)
    for i in range(b):
            x.append(b)
    print len(x)

यह विधि पुनरावृत्ति का उपयोग करता है, इसलिए समय जटिलता इष्टतम नहीं है मेरा मानना ​​है कि बिटवॉल ऑपरेशन के साथ कम स्तर पर काम करना सबसे अच्छा तरीका है


इस समस्या पर खुद को सी # में काम कर रहा था और सभी परीक्षण के मामलों को पास नहीं कर सका। मैं तो इस पर भाग गया

यहाँ सी # 6 में कार्यान्वयन है:

public int Sum(int a, int b) => b != 0 ? Sum(a ^ b, (a & b) << 1) : a;

यह पायथन पर मेरा कार्यान्वयन है यह अच्छी तरह से काम करता है, जब हम बाइट्स (या बिट्स) की संख्या जानते हैं।

def summ(a, b):
    #for 4 bytes(or 4*8 bits)
    max_num = 0xFFFFFFFF
    while a != 0:
        a, b = ((a & b) << 1),  (a ^ b)
        if a > max_num:
            b = (b&max_num) 
            break
    return b

सबसे अधिक वोट किए गए उत्तर काम नहीं करेगा यदि इनपुट विपरीत चिह्न के होते हैं निम्नलिखित हालांकि होगा मैंने एक ही स्थान पर धोखा दिया है, लेकिन केवल कोड को थोड़ा साफ रखने के लिए सुधार के स्वागत के लिए कोई भी सुझाव

def add(x, y):
if (x >= 0 and y >= 0) or (x < 0 and y < 0):
    return _add(x, y)
else:
    return __add(x, y)


def _add(x, y):
if y == 0:
    return x
else:
    return _add((x ^ y), ((x & y) << 1))


def __add(x, y):
if x < 0 < y:
    x = _add(~x, 1)
    if x > y:
        diff = -sub(x, y)
    else:
        diff = sub(y, x)
    return diff
elif y < 0 < x:
    y = _add(~y, 1)
    if y > x:
        diff = -sub(y, x)
    else:
        diff = sub(y, x)
    return diff
else:
    raise ValueError("Invalid Input")


def sub(x, y):
if y > x:
    raise ValueError('y must be less than x')
while y > 0:
    b = ~x & y
    x ^= y
    y = b << 1
return x

धोखा। आप संख्या को अस्वीकार कर सकते हैं और पहले से घटा सकते हैं :)

यह न मानें, एक बाइनरी योजक कैसे काम करता है। :)

संपादित करें: आह, मैंने पोस्ट की गई पोस्ट के बाद आपकी टिप्पणी देखी

बाइनरी अतिरिक्त का विवरण यहां है