LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: pmj_pedro em 06 de Fevereiro de 2013, 00:41

Título: Operar sobre variaveis do tipo long
Enviado por: pmj_pedro em 06 de Fevereiro de 2013, 00:41
Estou a corre este programa:
Código: [Seleccione]
void setup(){
  Serial.begin(57600);
}

void loop(){
  long code = 0xFFFF;
  byte n=32;
  while( n>0 ){
    if( (code & (1<<n)) != 0)
     break;
    n--;
  }
  Serial.print('\t');
  Serial.print(n);
  delay(1000);
}
Que deveria dizer o numero do bit em que acha o primeiro 1, mas ele so me diz para valores com menos de 16bits, eu compreendo como isto acontece, mas queria saber como posso por isto a funcionar

O resultado na consola
Citar
   15   15   15   15   15   15   15
Título: Re: Operar sobre variaveis do tipo long
Enviado por: senso em 06 de Fevereiro de 2013, 01:52
Experimenta fazer um cast da variavel n para long,e eu prefiro usar os designadores de variaveis diferentes, assim:
Código: [Seleccione]
void setup(){
  Serial.begin(57600);
}

void loop(){
  int32_t code = 0xFFFF;
  uint8_t n=32;
  while( n>0 ){
    if( (code & (1<<(int32_t)n)) != 0)
     break;
    n--;
  }
  Serial.print('\t');
  Serial.print(n);
  delay(1000);
}


E provavelmente será problema de variaveis com/sem sinal, e talvez atrofio do print.
Título: Re: Operar sobre variaveis do tipo long
Enviado por: pmj_pedro em 06 de Fevereiro de 2013, 02:28
Experimenta fazer um cast da variavel n para long,e eu prefiro usar os designadores de variaveis diferentes, assim:
Código: [Seleccione]
void setup(){
  Serial.begin(57600);
}

void loop(){
  int32_t code = 0xFFFF;
  uint8_t n=32;
  while( n>0 ){
    if( (code & (1<<(int32_t)n)) != 0)
     break;
    n--;
  }
  Serial.print('\t');
  Serial.print(n);
  delay(1000);
}


E provavelmente será problema de variaveis com/sem sinal, e talvez atrofio do print.

Continua sem funconiar e nao é problema do print

Código: [Seleccione]
void setup(){
  Serial.begin(57600);
}

void loop(){
  int32_t code = 0xFFFF;
  uint8_t n=32;
  while( n>0 ){
    if( (code & (1<<(int32_t)n)) != 0){
      Serial.println(n);
      break;
    }
    n--;
  }
  delay(1000);
}

Continua so a imprimir 15
Título: Re: Operar sobre variaveis do tipo long
Enviado por: senso em 06 de Fevereiro de 2013, 02:29
Qual é a ideia mesmo?
Tira-lhe o break ver no que dá.
Título: Re: Operar sobre variaveis do tipo long
Enviado por: pmj_pedro em 06 de Fevereiro de 2013, 02:51
imprime de 15 a 1

Estou a ler um sensor que recebe um codigo, eu armazeno e depois quer testar desda posiçao 32 ate encontrar o primeiro 1, para testar o start bit
Título: Re: Operar sobre variaveis do tipo long
Enviado por: tarquinio em 06 de Fevereiro de 2013, 03:16
Bem este deixou-me curioso... :)
Após uns testes, já descobri o problema... (aliás problemas :P )

O primeiro está na linha:
Código: [Seleccione]
if( (code & (1<<n)) != 0)
Aquele 1, como não foi dito nada em contrário, é um int de 16 bits, logo não serve...
Na mesma linha, esquecendo o detalhe dos 16 bits, o shift maior deveria ser <<31 e não <<32, pois o 1 inicial está já no 1º bit, logo so tem de andar 31x.

E por ultimo, mas não menos importante... Algo que nenhum de nós reparou e tava mmo á vista...
0xFFFF são só 2 bytes... :P Logo precisas de 0xFFFFFFFF.

Portanto precisas de algo do tipo:
Código: [Seleccione]
  unsigned long code =  0xFFFFFFFF;
  byte n=32;
  while( n>0 ){
      Serial.println(((unsigned long)1<<(n-1)), BIN);
    if( (code & ((unsigned long)1<<(n-1))) != 0)
     break;
    n--;
  }
  Serial.print('\t');
  Serial.print(n);
Título: Re: Operar sobre variaveis do tipo long
Enviado por: pmj_pedro em 06 de Fevereiro de 2013, 03:32
Espetaculo, ja funciona
O numero de deslcomaneto ja tinham reparado que era 32, mas depois quando quis alterar isso para sizeof(long)-1, vi que nada alterava e voltei eu a escrever o numero, obrigado por esse reparo

Estava com medo que tivesse que deparar o long em byte e fazer byte a byte o shift, mas assim funciona
Obgd
Título: Re: Operar sobre variaveis do tipo long
Enviado por: senso em 06 de Fevereiro de 2013, 14:41
Pois é, esqueci-me que o 1 tambem tem de levar cast, basta meteres assim:
1UL
Título: Re: Operar sobre variaveis do tipo long
Enviado por: tarquinio em 06 de Fevereiro de 2013, 15:43
Olha essa sintaxe n conhecia... :)
Título: Re: Operar sobre variaveis do tipo long
Enviado por: senso em 06 de Fevereiro de 2013, 16:36
Não é ANSI C, logo funciona no avr-gcc por causa de defines que ele tem lá no inttypes e isso, não é algo universal.
Título: Re: Operar sobre variaveis do tipo long
Enviado por: pmj_pedro em 06 de Fevereiro de 2013, 18:40
Eu tenho a impressão que já vi isso quando se define a frequência do arduino
Título: Re: Operar sobre variaveis do tipo long
Enviado por: senso em 06 de Fevereiro de 2013, 20:58
Sim, tipo isto:
#define F_CPU 16000000UL
Título: Re: Operar sobre variaveis do tipo long
Enviado por: StarRider em 06 de Fevereiro de 2013, 22:29
Boas,

Por essas e por outras é que as constantes numéricas que envolvam manipulação de bits devem ser sempre
expressas em hexa com a dimensão (word, dword, qword) que a variável de referencia, ex:  0x00000001 << n-1
como a subtracção (neste caso "n-1") tem precedência sobre o bitwise nem sequer é necessário parêntesis.

Abraços,
PA
Título: Re: Operar sobre variaveis do tipo long
Enviado por: pmj_pedro em 07 de Fevereiro de 2013, 00:30
Boas,

Por essas e por outras é que as constantes numéricas que envolvam manipulação de bits devem ser sempre
expressas em hexa com a dimensão (word, dword, qword) que a variável de referencia, ex:  0x00000001 << n-1
como a subtracção (neste caso "n-1") tem precedência sobre o bitwise nem sequer é necessário parêntesis.

Abraços,
PA

Quando trabalhava com um pic32, para mim fazia sentido usar, mas depois quando se trabalha com atmega 8bits, acho que nao é assim tao importante

Mas tb so nao uso mais, pk ainda nao tenho mt bem assimilado o binario e o hexadecimal