Hola foreros. Tengo este codigo y lo que quiero es que devuelva 1 si el simbolo pasado a la funcion es alguno de los definidos arriba. Habia pensado en hacerle un corrimiento de bits dependiendo la posicion del bit encendido. por ej >> (int)sqrt(0x3FF % sym + 1) pero el problema es que este metodo no funciona con algunas constantes.. como puedo saber la posicion del bit encendido para moverlo y que si el argumento concuerde con alguna constante devuelva 1?
#define BACKSLASH 0x0001
#define SLASH 0x0002
#define COLON 0x0004
#define ASTERISK 0x0008
#define QUESTION 0x0010
#define QUOTES 0x0020
#define LESS 0x0040
#define GREATER 0x0080
#define PIPE 0x0100
int is_symbol(int sym)
{
return ((BACKSLASH | SLASH | COLON | ASTERISK | QUESTION | QUOTES | LESS | GREATER | PIPE) & sym);
}
Gracias de antemano! :D
El problema son los valores que puede estar tomando sym, es decir si el valor de sym no es potencia de dos te va a dar problemas
return ((BACKSLASH | SLASH | COLON | ASTERISK | QUESTION | QUOTES | LESS | GREATER | PIPE) & sym);
hola, no entiendo muy bien lo que haces pues estas haciendo un OR con todas las constantes. esto se traduce en que las estas sumando a nivel de bit. como ejemplo mas sencillo para que veas lo que pasa, mira esto:
a = 4 = ...0100
b = 6 = ...0110
a | b = 4 | 6 = ...0110 = 6
como veras, no tiene mucho sentido para hacer lo que tu quieres hacer ya que acabas haciendo un AND con algo extraño que no representa nada. ademas, si fuera el caso de que eso fuera correcto, tu funcion seguiria sin devolver 1 o 0, ya que por ejemplo, si el simbolo fuera el QUESTION:
QUESTION=0x10
sym=0x10
QUESTION & sym = 0x10 = 16
asi pues tu funcion devolveria 16. no te olvides que las operaciones a nivel de bit son en paralelo, es decir, el bit 0 de un numero con el bit 0 del otro, el bit 1 con el bit 1, etc.
en lugar de eso, si lo que quieres es que la funcion devuelva 1 cuando coincida con alguna de las constantes, y quieres hacerlo aplicando alguna operacion a nivel de bits, una solucion podria ser esta:
#define BACKSLASH 0x0001
#define SLASH 0x0002
#define COLON 0x0004
#define ASTERISK 0x0008
#define QUESTION 0x0010
#define QUOTES 0x0020
#define LESS 0x0040
#define GREATER 0x0080
#define PIPE 0x0100
#define NUMSYM 9
int is_symbol(int sym) {
int i, symbols[]={BACKSLASH, SLASH, COLON, ASTERISK, QUESTION, QUOTES, LESS, GREATER, PIPE};
for (i=0; i<NUMSYM; i++)
if (symbols[i]^sym == 0) return 1;
return 0;
}
donde uso la operacion XOR que dara 0 si los dos numeros son iguales. como veras es lo mismo que usar en la condicion del if un symbols[ i]==sym, pero lo puse por pedir que fuera con operaciones de bits.
si lo que quieres es que la funcion sea de 1 solo return, esto te podria servir:
int is_symbol(int sym) {
return !(BACKSLASH^sym && SLASH^sym && COLON^sym && ASTERISK^sym && QUESTION^sym && QUOTES^sym && LESS^sym && GREATER^sym && PIPE^sym);
}
aunque sinceramente no se que tan eficiente es respecto a la primera version que es mas facil de entender.
un saludo!
Cita de: xiruko en 5 Noviembre 2012, 23:20 PMsi lo que quieres es que la funcion sea de 1 solo return, esto te podria servir:
int is_symbol(int sym) {
return !(BACKSLASH^sym && SLASH^sym && COLON^sym && ASTERISK^sym && QUESTION^sym && QUOTES^sym && LESS^sym && GREATER^sym && PIPE^sym);
}
aunque sinceramente no se que tan eficiente es respecto a la primera version que es mas facil de entender.
Tiene la misma eficiencia. Ello porque en el caso de operador lógico AND si el operando a la izquierda es falso el derecho no se evalúa, en otras palabras la evaluación termina en cuanto uno de los operando en tu expresión sea cero (indicando que coincidió con alguna de las macros).
Cita de: HRSLASH en 5 Noviembre 2012, 19:14 PM
Hola foreros. Tengo este codigo y lo que quiero es que devuelva 1 si el simbolo pasado a la funcion es alguno de los definidos arriba.
Eso implica que se deben cumplir tres condiciones:
1) Ser mayor o igual que 1.
2) Ser menor o igual que 256.
3) Ser una potencia de dos (en binario el numero tiene solo un bit a uno).
Combinando los tres tenemos:
int is_symbol(int x)
{
return x >= 1 && x <= 256 && (x & x - 1) == 0;
}
Un saludo
Muchas gracias a todos por las respuestas! Finalmente me he quedado con la que propuso rir3760 funciona perfecto!! :D