2016-02-29 14 views
6

Jest this postu, który niedawno otrzymał jakiś niezwykły bukiet upvotes, prosząc o operatora w C
+ To pokazuje następujące realizacja:Czy ta pełna implementacja dodatku jest poprawna?

// replaces the + operator 
int add(int x, int y) { 
    while(x) { 
     int t = (x & y) <<1; 
     y ^= x; 
     x = t; 
    } 
    return y; 
} 

Przypadkowo napisałem realizację siebie zbyt (an algorytm zeszyt) i wymyślił, że:

uint32_t bit_add(uint16_t a, uint16_t b) { 
    uint32_t carry = ((uint32_t) a & b) << 1; 
    uint16_t add = a^b; 

    return carry^add; 
} 

Przetestowałem go kilka razy i wydaje się działać. Chodzi o to, że jest znacznie szybszy niż implementacja ze wskazanego postu, bez żadnych skoków na x86.

Czy moja implementacja jest poprawna lub czy jest coś złego, o czym nie wiem?
Nie mogę sobie wyobrazić, że mój kod jest szybszy niż kod postu tak często oglądany i sprawdzany.

+0

Nie sprawdziłem, ale może to być poprawne. Nie zakładaj, że ludzie piszą najbardziej efektywny kod możliwy przez cały czas; Po tym wszystkim odpowiedzi były najczęściej tworzone dla problemów z zabawkami lub dla celów demonstracyjnych, a nie dla rzeczywistego użycia (+ jest jeszcze szybsze). – Cubic

+0

Dwa przykłady są różne, pierwszy działa jeden bit na instrukcję w pętli, w twoje wszystkie bity mają wpływ. Kompilator może również zoptymalizować twój kod. – purplepsycho

+0

Spróbuj dodać 3 i 7, wyprowadza 2. – Kenney

Odpowiedz

6

Twoja funkcja nie działa.

Prosty kontrprzykład jest 127 + 1.

Łatwo to zobaczyć. Numer 127 ma wszystkie najważniejsze zestawy 7 bitów do 1. And o numerze 1, a przesunięcie go o jeden w lewo daje wartość 2. Od tego momentu, używając operatora xor, nie ma kombinacji wartości, które mamy dostępne , może wytworzyć wartość większą niż 127.

+0

Crap, masz rację. Czy możesz wyjaśnić, dlaczego?Już mam zamiar rozpocząć debugowanie, ale wyjaśnienie sprawi, że odpowiedź będzie jeszcze doskonalsza, IMO ... – Downvoter

+0

@można poprawnie obliczyć słowa 'add' i' carry', ale w oświadczeniu "return" popełniłeś błąd! Tam właśnie potrzebujesz ** Loop ** – Lrrr

+0

@ cad Zobacz aktualizację. – 2501

Powiązane problemy