2012-06-18 21 views
7

¿Existe un buen patrón general para implementar tablas de verdad?patrón general para implementar tablas de verdad

Estoy volviendo a trabajar con algún código heredado (C++) y me acabo de dar cuenta de que la función con la que estoy trabajando equivale a una tabla de verdad con 3 entradas binarias y 8 salidas posibles. Aquí hay un ejemplo de dos de las ocho pruebas y salidas correspondientes:

// - + + 
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; 

Básicamente me gustaría saber si hay un más limpio, más fácil de mantener/extensible * manera de configurar esto.

  • ¿Qué ocurre si se agrega otra entrada? Entonces, la cantidad de sentencias if necesarias sería 16, lo cual, en mi opinión, sería demasiado complicado de manejar con el patrón actual.
  • ¿Qué pasa si varios de los combos de entrada se asignan a la misma salida?

* La base de código es un modelo de ecosistema utilizado en la academia, por lo que el mantenimiento y la extensión equivalen a cosas similares según la perspectiva del codificador.

+0

¿Seguro? es dst5 = 0.0 en otro lugar, o fuera del alcance? –

+0

no estoy seguro de entender? en realidad, hay una prueba en la parte superior de la función: if (dst5 == 0.0) dst5 = 0.001; que creo que es un error (compare el número de punto flotante para la igualdad) – tbc

+0

(demasiado tarde para modificar el comentario anterior) Solucionarlo aquí: no estoy seguro de que lo entiendo? en realidad hay una prueba como esta: if (dst5 == 0.0) dst5 = 0.001; para cada entrada en la parte superior de la función. De hecho, creo que esto es un error (compare el número de coma flotante para la igualdad), pero al menos se ocupa de la posibilidad de que cada entrada sea 0. – tbc

Respuesta

4

Una matriz es una tabla.

Una secuencia de valores de verdad booleanos es un número binario.

Las matrices están indexadas por número.

Sooooo .....

Se podría definir una función para cada cálculo:

// - + + == 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); 
} 

// ... 

Entonces declarar una matriz de punteros de función:

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

Entonces índice en la matriz utilizando las condiciones booleanas como dígitos binarios:

func_type f = funcs[ (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ]; 
thawpct = f(prevdst5, dst5, nextdst5); 
  • ¿Qué ocurre si se agrega otra entrada? (A continuación, el número de pruebas sería 16, que en mi opinión sería difícil de manejar con el patrón actual)

se duplica el tamaño de la matriz y añadir f8, f9 etc., si son diferentes cálculos necesitaba, pero sólo se agrega la nueva prueba una vez, en el índice de matriz:

func_type f = funcs[ (cond<<3) | (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ]; 
  • ¿Qué pasa si varios de los combos de entrada debe asignar a la misma salida?

tienda el mismo puntero de función en varios elementos de la matriz:

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

se podía mantener un mapeo de 3 (o n) los valores de la función adecuada que necesita ser realizado.A continuación, repita la función en este mapa según el estado true/false de las condiciones y ejecútelo.

De esta manera se tendría un mapa 3 dimensional (con un tamaño de 2 en todas las Dimensiones)

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

Si dos entradas se asignan al mismo resultado, simplemente coloque esas casillas una al lado de la otra y sin errores. Incluso más simple que mi sugerencia de matriz. –

+0

He visto el operador condicional anteriormente, pero estoy confundido por el "1 << 0" en el segundo operando? Johathan Wakely usó algo similar en su respuesta ... – tbc

+0

@myself - lo encontré operador de desplazamiento: http://stackoverflow.com/questions/141525/absolute-beginners-guide-to-bit-shifting – tbc

Cuestiones relacionadas