Autor Tema: Validando un IF  (Leído 12368 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Validando un IF
« en: 16 de Marzo de 2008, 16:02:20 »
Hola

Estaba trabajando con una instrucción if para aplicar una máscara. Primero pego el código para explicarme  :mrgreen:

Código: [Seleccionar]
#define PAD_BUTTON_A 0x0100
#define PAD_BUTTON_B 0x0200
#define PAD_TRIGGER_Z 0x0010

int buttonsdown; //variable de 32 bits que almacena los botones presionados

...
   
    //Si presiona A y B activa motor del control, buttonsdown vale 0x0300
    if((buttonsdown&(PAD_BUTTON_B|PAD_BUTTON_A))==(PAD_BUTTON_B|PAD_BUTTON_A))
        motor=1;
    //Si presiona A y Z desactiva motor del control, buttonsdown vale 0x0110
    if((buttonsdown&(PAD_TRIGGER_Z|PAD_BUTTON_A))==(PAD_TRIGGER_Z|PAD_BUTTON_A))
        motor=0;

En el código anterior si se aplica la máscara de A+B (0x0300) sobre buttonsdown (0x0300) y el resultado da 0x0300, entonces el if ejecuta su contenido, no hay problema. En caso contrario no ejecuta su contenido.

Tengo entendido que el contenido de un IF solo se ejecuta si lo que evalúa es diferente a cero, pero si reduzco el código de mi programa a lo siguiente:

Código: [Seleccionar]
if(buttonsdown&(PAD_BUTTON_B|PAD_BUTTON_A))
        motor=1;

El contenido ya no se ejecuta. Si se evalúa, el resultado que tiene el if es 0x0300, el cual es diferente a cero, pero el if no hace nada.

¿Cuál es la diferencia? No entiendo porque funciona solo si hago la comparación ==.
« Última modificación: 16 de Marzo de 2008, 16:53:16 por migsantiago »

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Validando un IF
« Respuesta #1 en: 16 de Marzo de 2008, 16:08:18 »
¿Qué hace la función buttonsdown&?

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Validando un IF
« Respuesta #2 en: 16 de Marzo de 2008, 16:52:39 »
ah perdón, se me olvidó comentar que buttonsdown es una variable de 32 bits que almacena en cada bit un uno o un cero, dependiendo de si un botón es presionado o no.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Validando un IF
« Respuesta #3 en: 16 de Marzo de 2008, 16:58:29 »
Pues entonces me quedo con la misma duda que tú, no veo porqué no funciona.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Validando un IF
« Respuesta #4 en: 16 de Marzo de 2008, 17:05:18 »
Mmhhh, voy a pegar todo el código. Al principio cuando checo si solo un botón es presionado, el if funciona correctamente, pero cuando uno dos máscaras (a+b) el if ya no funciona, cosa rara  :D

Código: [Seleccionar]
//Programa que lee el estado del control 1
//controla también el motor
//san.link@yahoo.com.mx

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ogcsys.h>
#include <gccore.h>

static void *xfb = NULL;
static GXRModeObj *rmode = NULL;

//Inicialización del video
void video_inicia()
{
VIDEO_Init();
PAD_Init();
switch(VIDEO_GetCurrentTvMode()) {
    case VI_NTSC:
            rmode = &TVNtsc480IntDf;
            break;
    case VI_PAL:
            rmode = &TVPal528IntDf;
            break;
    case VI_MPAL:
            rmode = &TVMpal480IntDf;
            break;
    default:
            rmode = &TVNtsc480IntDf;
            break;
}
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(xfb);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
}

//Subfunción que imprime 4 espacios
void espacios()
{
    printf("    ");
}

//Subfunción que imprime un caracter y 3 espacios
void caracter()
{
    printf("%c   ",233);
}

/////////////////////////////////////////////////////////////////////////////////////////
//Función principal
int main()
{   
//Declaro mis variables
int buttonsdown; //almacena qué botones se apretaron en el control 1
s8 stickx,sticky,c_x,c_y; //stick normal y stick c
u8 trigr,trigl; //nivel de presión de botones l y r
bool motor=0; //activa o desactiva el motor
   
//Inicia video
video_inicia();
   
//Comienza mi programa
while(1)
{
    VIDEO_WaitVSync();
    printf("\n--------------------------\n");
    printf("Sanlink\n");
    printf("Estado del control 1\n");
    printf("A + B - Activar motor\n");
    printf("A + Z - Desactivar motor\n");
   
    PAD_ScanPads();
    //lee los recién presionados y los anteriores
    buttonsdown = PAD_ButtonsDown(0)|PAD_ButtonsHeld(0);
   
    c_x=PAD_SubStickX(0);
    c_y=PAD_SubStickY(0);
   
    stickx=PAD_StickX(0);
    sticky=PAD_StickY(0);
   
    trigl=PAD_TriggerL(0);
    trigr=PAD_TriggerR(0);
   
    printf("\nBotones presionados:\n");
    printf("A   B   X   Y   Z   ST  L   R   UP  DW  LF  RT\n");
    if(buttonsdown&PAD_BUTTON_A) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_B) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_X) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_Y) caracter(); else espacios();
    if(buttonsdown&PAD_TRIGGER_Z) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_START) caracter(); else espacios();
    if(buttonsdown&PAD_TRIGGER_L) caracter(); else espacios();
    if(buttonsdown&PAD_TRIGGER_R) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_UP) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_DOWN) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_LEFT) caracter(); else espacios();
    if(buttonsdown&PAD_BUTTON_RIGHT) caracter(); else espacios();
   
    printf("\n");
   
    printf("Stick   - X:%d Y:%d\n",stickx,sticky);
    printf("Stick C - X:%d Y:%d\n",c_x,c_y);
    printf("Bot R - %u\n",trigr);
    printf("Bot L - %u\n",trigl);
    printf("Motor - %d\n",motor);
    printf("Buttonsdown: %04x\n",buttonsdown);
   
    //Si presiona A y B activa motor del control
    if((buttonsdown&(PAD_BUTTON_B|PAD_BUTTON_A))==(PAD_BUTTON_B|PAD_BUTTON_A))
        motor=1;
    //Si presiona A y Z desactiva motor del control
    if((buttonsdown&(PAD_TRIGGER_Z|PAD_BUTTON_A))==(PAD_TRIGGER_Z|PAD_BUTTON_A))
        motor=0;
    if(motor)
        PAD_ControlMotor(PAD_CHAN0,PAD_MOTOR_RUMBLE);
    else
        PAD_ControlMotor(PAD_CHAN0,PAD_MOTOR_STOP);
   
    sleep(1); //espera 1 segundo para actualizar información
   
}
return(0);
}

Desconectado Menta

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 611
Re: Validando un IF
« Respuesta #5 en: 16 de Marzo de 2008, 17:25:53 »
La verdad es que debería funcionar igual, tampoco sé por qué no funciona, pero me parece que al margen de eso hay un error de lógica. Para ser más claro voy a remplazar PAD_BUTTON_A y PAD_BUTTON_B por 0x100 y 0x200 respectivamente.

if((buttonsdown&(0x200|0x100))==(0x200|0x100))
        motor=1;

si los pines 8 y 9 de buttonsdown son 1 te queda if((0x300&0x300) == 0x300)  implica que es verdadero

Mientras que:

if(buttonsdown&(0x200|0x100))
        motor=1;

imaginate que solo está presionado el boton del bit 8 ==> ej buttonsdown = 0x100 (el boton A solo)

te queda       if(0x100 & 0x300)  y te daría verdadero si llegara a funcionar aunque en realidad no se presionaron los dos botones a la vez

En resumen la primera forma pregunta si se presionaron los 2 y la segunda si se presionó alguno de los 2
     

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Validando un IF
« Respuesta #6 en: 16 de Marzo de 2008, 17:35:50 »
Sí es cierto, solo usando buttonsdown & 0x0300 no verifica que ambos se hayan presionado, solo uno de los dos.

Pero aún así debería ejecutarse el if.

Bueno, gracias, me diste otra perspectiva del problema.

Desconectado Menta

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 611
Re: Validando un IF
« Respuesta #7 en: 16 de Marzo de 2008, 17:47:30 »
Por nada.

Probé recién todas las combinaciones que se me ocurrieron con variables de distintos largos 32, 16, 8 mezcladas, incluso metiendo funciones dentro de la parte de evaluación del if y siempre funciona (con la versión 3.235 de CCS). Así que si tú puedes asegurar que los pines 8 y 9 de buttonsdown de 32 bits son unos al momento de evaluar la sentencia.
Lo único que puede ser es algún bug del compilador.  :?

Saludos.
     

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Validando un IF
« Respuesta #8 en: 16 de Marzo de 2008, 19:12:42 »
Hmmmm...

¿Así tampoco va, eh?

if((buttonsdown & (PAD_BUTTON_B|PAD_BUTTON_A)))

Digo porque ya va más de una vez que el compilador sin los paréntesis hasta en las partes mas obvias me hace cualquiera...

:D
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Validando un IF
« Respuesta #9 en: 16 de Marzo de 2008, 20:12:08 »
Pues no, tampoco exagerándole con los paréntesis  :D

Es un bug raro, pero no me sorprende, el compilador es de libre distirbución y está hecho por fanáticos, no por compañías súper experimentadas.  :)

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Validando un IF
« Respuesta #10 en: 16 de Marzo de 2008, 21:18:13 »
Hola nose si el CCS lo soporta pero en ANSI C las constantes de 32 bits de deben colocar con el sufijo UL, ejemplo
Código: [Seleccionar]
#define PAD_BUTTON_A    0x0100UL
#define PAD_BUTTON_B    0x0200UL
#define PAD_TRIGGER_Z  0x0010UL
Esto fuerza al compilador a usar una constante de 32 bits, que opera directamente con el operando de 32 bits, en este caso ( buttonsdown ), creo, no lo puedo asegurar, es que en tu codigo se esta produciendo lo que se llama "integral promotion" ...
Saludos !

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Validando un IF
« Respuesta #11 en: 17 de Marzo de 2008, 00:47:13 »
Hola Richi

Probé agregando los define y el resultado fue el mismo, el problema está en la revisión del if.

Por cierto, el compilador que uso no es CCS, es un compilador gcc que funciona con un kit llamado devkitPro para compilar programas para el procesador PowerPC.

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Validando un IF
« Respuesta #12 en: 17 de Marzo de 2008, 15:43:10 »
Hola, que raro que GCC tenga un bug de esta naturaleza  :shock:
Saludos !

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Validando un IF
« Respuesta #13 en: 17 de Marzo de 2008, 15:57:55 »
Hola Richi

Probé agregando los define y el resultado fue el mismo, el problema está en la revisión del if.

Por cierto, el compilador que uso no es CCS, es un compilador gcc que funciona con un kit llamado devkitPro para compilar programas para el procesador PowerPC.

Mirando rápidamente el problema y sin probar nada yo revisaría hacer un par de cosas

1) desactivar las optimizaciones del compilador
2) comenta las lineas por debajo del if, las que precisamente hacen que motor = 0

Y si tienes tiempo comentanos como te fué.

Me huele a que el compilador esté optimizando algo por algún criterio de que una condición no se dará nunca y por ende simplifica alguna línea.

Tal vez determina que el 1er if, será sobreescrito por el resultado del segundo if.





- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Validando un IF
« Respuesta #14 en: 17 de Marzo de 2008, 18:00:54 »
Hola Mauricio

No sé como deshabilitar las optimizaciones del compilador. Funciona en una ventana de consola de windows, pero corre un programa llamado migw32 que simula un linux pequeño.



Luego para compilar solo me pongo en el directorio de mi proyecto y le doy el comando make. Make usa un archivo makefile el cual siempre copio y pego, porque no tengo idea de cómo se edita.

Al final make genera un ejecutable, el cual corro en mi gamecube y veo todo en la tele.


 

anything