2012-06-18 11 views
7

Czy istnieje dobry ogólny wzorzec wdrażania tabel prawdy?ogólny wzór implementacji tabel prawdy

Jestem ponownie pracuje trochę starszych kod (C++) i po prostu sobie sprawę, że funkcja Pracuję z kwot do tabeli prawdy z 3 wejściami cyfrowymi i 8 możliwych wyjść. Oto przykład dwóch z ośmiu testów i odpowiadających im wyjść:

// - + + 
if ((prevdst5 < 0.0) && (dst5 > 0.0) && (nextdst5 > 0.0)){ 
    thawpct = (dst5/(dst5 - prevdst5)); 
} 

// - - + 
if ((prevdst5 < 0.0) && (dst5 < 0.0) && (nextdst5 > 0.0)){ 
    thawpct = (nextdst5/(nextdst5 - dst5)); 
} 

// other cases... 

return thawpct; 

zasadzie zastanawiam się, czy jest czystsze, bardziej linkujących/rozszerzalny * sposób to skonfigurować.

  • Co się stanie, jeśli zostanie dodane kolejne wejście? Wtedy liczba potrzebnych instrukcji to 16, co moim zdaniem byłoby zbyt kłopotliwe, aby poradzić sobie z bieżącym wzorcem.
  • Co należy zrobić, jeśli kilka zestawów danych wejściowych ma odwzorować to samo wyjście?

* Baza kodów jest modelem ekosystemu stosowanym w środowisku akademickim, więc czynności konserwacyjne i rozszerzenie są podobne do rzeczy zależnych od perspektywy programisty.

+0

Czy jesteś pewien? czy dst5 = 0.0 gdzieś indziej, czy poza zakresem? –

+0

Nie jestem pewien, czy rozumiem? faktycznie istnieje test na górze funkcji: jeśli (dst5 == 0,0) dst5 = 0,001; co moim zdaniem jest błędem (porównaj liczbę zmiennoprzecinkową dla równości) – tbc

+0

(za późno, aby zmienić poprzedni komentarz) Napraw tutaj: nie jestem pewien, rozumiem? faktycznie istnieje taki test: if (dst5 == 0,0) dst5 = 0,001; dla każdego wejścia na górze funkcji. Właściwie uważam, że to błąd (porównaj liczbę zmiennoprzecinkową dla równości), ale przynajmniej dba o to, aby każde wejście było 0. – tbc

Odpowiedz

4

Tablica jest tabelą.

Sekwencja wartości logicznych prawdy jest liczba binarna.

Tablice są indeksowane przez liczby.

Baaardzo .....

Można zdefiniować funkcję dla każdego obliczenia:

// - + + == 0 1 1 == 3 
inline double f3(double prev, double curr, double next) 
{ 
    return curr/(curr - prev); 
} 

// - - + == 0 0 1 == 1 
inline double f1(double prev, double curr, double next) 
{ 
    return next/(next - curr); 
} 

// ... 

Następnie zadeklarować tablicę wskaźników Funkcja:

typedef double (*func_type)(double, double, double); 
func_type funcs[8] = { 
    f1, f2, // ... 
}; 

Następnie indeks do tablicy używając logicznych warunków jak dwójkowym:

func_type f = funcs[ (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ]; 
thawpct = f(prevdst5, dst5, nextdst5); 
  • Co się stanie, jeśli zostanie dodane kolejne wejście? (Wtedy liczba testów byłoby 16, co moim zdaniem byłoby kłopotliwe zarządzać z aktualnym wzorem)

można podwoić rozmiar tablicy i dodać f8, f9 itd jeśli różne obliczenia są potrzebne, ale tylko dodać nowy test raz, w indeksie tablicy:

func_type f = funcs[ (cond<<3) | (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ]; 
  • Co jeśli kilku combo wejściowych należy mapować do tego samego wyjścia?

przechowywać ten sam wskaźnik funkcji w kilku elementów tablicy:

func_type funcs[8] = { 
    f1, f2, f3, f1, f1, // ... 
}; 
0

Można zachować odwzorowanie 3 (lub n) wartości do odpowiedniej funkcji, które muszą być wykonane.Następnie zapętlić funkcję na tej mapie na podstawie stanu warunkowego i wykonać to.

W ten sposób będziesz mieć 3 wymiarowej mapy (o wielkości 2 we wszystkich wymiarach)

8
int condition = (prev >= 0 ? (1<<0) : 0) + 
       (cur >= 0 ? (1<<1) : 0) + 
       (next >= 0 ? (1<<2) : 0); 

switch (condition) { 
    case 0: // - - - 
    case 1: // + - - 
    case 2: // - + - 
    case 3: // + + - 
    case 4: // - - + 
    case 5: // + - + 
    case 6: // - + + 
    case 7: // + + + 
} 
+2

Jeśli dwa wejścia odwzorowują na to samo wyjście, umieszczasz je obok siebie i wpadają. Jeszcze prostsze niż moja sugestia tablicowa. –

+0

Widziałem wcześniej operatora warunkowego, ale jestem zdezorientowany przez "1 << 0" w drugim operandzie? Johathan Wakely użył czegoś podobnego w swojej odpowiedzi ... – tbc

+0

@myself - znalazłem operatora zmiany: http://stackoverflow.com/questions/141525/absolute-beginners-guide-to-bit-shifting – tbc