Dodaję liczby 32-bitowe, ale zapisując je i używając do tego liczb tylko 16-bitowych. Mam prostą pętlę w pętli. W pierwszej pętli zwiększam counter 32-bitowy o 1, w drugiej wykonuję proste sumowanie 16 razy:
#include <cstdint>
#include <cstdio>
#include <bitset>
#include<iostream>
#include <string>
uint16_t add_hi(uint16_t a, uint16_t b)
{
uint16_t sum = a + b;
return sum > std::max(a, b) ? 0 : 1;
}
int main()
{
uint32_t s;
uint32_t weyl = 0;
uint32_t counter = 1;
uint16_t s_low;
uint16_t s_hi;
uint16_t weyl_low = 0;
uint16_t weyl_hi = 0;
uint16_t counter_low = 1;
uint16_t counter_hi = 0;
uint32_t wynik;
for (int i = 0; i < 100; i++)
{
counter += 1;
s = counter;
weyl = 0;
counter_hi = add_hi(counter_low, 1) + counter_hi;
counter_low = counter_low + 1;
s_low = counter_low;
s_hi = counter_hi;
weyl_low = 0;
weyl_hi = 0;
for (int i = 0; i < 16; i++)
{
weyl += s;
weyl_hi = add_hi(weyl_low, s_low) + weyl_hi + s_hi;
weyl_low = weyl_low + s_low;
}
wynik = (weyl_hi << 16) | weyl_low;
std::cout << weyl << " " << wynik << "\n";
}
return 0;
}
Wynik "wynik", czyli złożenie dwóch 16-bitowych liczb w jedną 32-bitową powinien być takim sam jak weyl - czyli rezultat obliczany na normalnych 32-bitowych liczbach. Funkcja add_hi oblicza górne bity będące wynikiem dodawania dwóch 16-bitowych liczb (zawsze będzie to 1 lub 0), w ten sposób możemy obliczyć górne bity będące wynikiem dodawania dwóch 32-bitowych liczb, używając tylko 16-bitowych liczb, czyli weyl_hi. Dolne bity weyl_low liczy się trywialnie.
weyl i wynik powinny być identyczne, a nie są. Z jakichś powodów weyl_hi w drugiej pętli jest ciągle równe 1, pomimo, że powinno być równe 0. Nie mam pojęcia skąd tam do cholery bierze się ta jedynka, skoro przy tak małych pętlach nie otrzymujemy rezultatów większych niż 16-bitowe.
Jak zaimplementować coś tak prostego jak 32-bitowe:
weyl += s;
Ale używając do tego liczb 16-bitowych? Weyl_hi i weyl_low mają się składać w taki sam wynik jak weyl. Ktoś znajduje tu błąd?
PS Już w pierwszym kroku pętli for (int i = 0; i < 16; i++) okazuje się, że weyl_hi jest równe 1, pomimo, że jego składowe powinny być równe zero, bo add_hi(weyl_low, s_low) powinno wynosić zero i weyl_hi + s_hi też powinno wynosić zero. Suma zer to nie zero.