Bom dia pessoal.
Este "erro" da IDE do Arduíno na minha opinião não deveria acontecer.
Descrição do sketck:
Defino 2 variáveis com o tamanho byte e defino 2 valores em hexadecimal.
byte K = 0x49;
byte M = 0x94;
Em seguida imprimo a parte alta da primeira variável
" Serial.println((K & 0xF0), HEX); "
e imprimo deslocando 4 bits para esquerda a segunda variável
" Serial.println((M 4), HEX); "
Como cada variável foi definida como byte (8 bits),
o resultado deveria ser também somente um byte,
mas o resultado aparece assim
40 primeiro print
940 segundo print 2 bytes ??
Code de texto em anexo.
RV
Tags:
Não deveria, realmente.
Faz falta nessas horas poder ver o arquivo intermediário de compilação, algo como:
https://forum.arduino.cc/index.php?topic=116132.0
Nunca usei isso em Arduino, mas no 8051 quebrava um galhão. Mostrava como comentário a linha em C e depois o que virou em ASM.
Boa tarde Rui,
Já passei por essa situação também - e é um resultado normal.
Na verdade você esta criando um novo número, quando insere zeros no lado direito (adicionando 4 bits) , usando a função " M > > 4 " bitshift right. No total seu número tem 12 bits.
https://www.arduino.cc/reference/en/language/structure/bitwise-oper...
Boa tarde José Gustavo Abreu Murta ,
seria normal se a variável não fosse do tamanho byte.
O link que você usou colou mostra operação com variável tamanho "int".
Neste caso sim, o deslocamento dentro de 16 bits pode conter 12 bits,
mas um deslocamento dentro de 8 bits não pode conter 12 bits.
Em linguagem C, quando usa-se um deslocamento maior que o tamanho da variável,
os bits excedentes são descartados.
Exemplo:
byte
X = 0x5F --> 0101 1111 X>>4 --> 0000 0101 e 1111 pro lixo pois o espaço
alocado para byte é de somente 8 bits.
RV
boa tarde RV.
Nota inicial: pessoal, o símbolo do shift para a esquerda do "C/C++", não aparece de jeito algum no texto aqui do Garagem, e por isso tive que substituir pelas palavras "shift left" nos trechos de código a seguir. Doidices.
Agora o post em si:
Conferindo o Arduino CC, vc tem toda razão RV, já que os bits deslocados para a esquerda serão descartados, conforme vemos na figura a seguir:
Mas aqui entra um coadjuvante que quer ser protagonista: a implementação overload na biblioteca primitiva do Arduino, para qualquer print. Para o tipo "byte", você pode ver essa implementação na figura a seguir:
Veja que esta é uma das funções overload para o print, especificamente a do "unsigned char", ou seja para o "byte".
O que ocorre é isto: apesar de vc estar usando uma variável do tamanho "byte", o "Parser" do Compilador no intuito de simplificar o código, expande a análise e assim copia o seu "(M shift left 4)" para dentro do overload do "print", ou seja, substitui a variável simbólica "b" do print com o "(M shift left 4)". Mas veja que o print definitivo é feito por "outro print' dentro do overload, e isso resulta nisso:
print ( (unsigned long) (M shift left 4), HEX );
E este último "print" que efetivamente fará o serviço, faz um casting e converte seu byte para "unsigned long". Bem, daí pra frente você já sabe o que vai acontecer: na impressão final os zeros não significativos serão descartados, mas o "9" do "(0x94 shift left 4)" estará lá firme e forte.
O motivo de terem feito isso no overload: eles consideraram que ao fazer o "casting" para um tipo maior, não haverá prejuízo para os dígitos do resultado. Mas não perceberam que isto pode descaracterizar o entendimento da variável quando se usa o "". Então podemos afirmar que acaba sendo um "bug", resultante da uma implementação particular da biblioteca primitiva do print, e ocorre quando o "Parser" do Compilador vai "expandir" a expressão para chegar ao código final.
Detalhe: na implementação da biblioteca primitiva do print, o mesmo casting é também feito para o tipo "word" (o "unsigned int"). E a mesma coisa para os tipos "signed", mas neste caso o casting é feito usando o "long".
Espero ter ajudado a elucidar o "mistério".
Abrçs
Elcids
Boa noite Sr. Elcids Chagas,
apesar das obervações do Sr. serem pertinentes, tenho que discordar.
Se observar e usar o code que anexei, o problema não acontece somente no método print.
Ocorre também na instrução "if",
A razão para que eu usasse o método print foi para debug, pois o " if" não funcionava como eu queria.
Att.
Rui
realmente RV.
Porém neste caso, o resultado do "if" será sempre uma variável booleana, a qual está desvinculada de tamanhos e dígitos significativos (embora de fato também seja um tipo inteiro, como bem sabemos). Por esse motivo o Compilador GCC ao perceber que toda a expressão é composta apenas por inteiros, ele toma a liberdade de expandir o resultado para o maior tipo inteiro que trabalha (pelo motivo de não haver prejuízo para quaisquer dígitos, como mencionei no post anterior), e acaba tendo o resultado que você visualizou.
Isto não é uma inconsistência no processamento da linguagem, porque "eles" consideram que você pode estreitar a avaliação usando um "casting" específico, como nisso:
"(byte) (M shift left 4)"
O Compilador GCC, assim como tantos outros, está cheio dessas pequenas armadilhas (eu já fui vítima disso também). Mas não somos nós que ditamos como eles funcionam, e sim a comunidade que trabalha nisso.
Abrçs
Elcids
Concordo com o Elcids =
"Mas não somos nós que ditamos como eles funcionam, e sim a comunidade que trabalha nisso"
Outro caso clássico, e irritante, é quando você faz isso:
//--------------------------------------------------
#define menos_um -1
byte TESTE = menos_um;
//--------------------------------------------------
neste caso já dá erro em tempo de compilação. Então perguntamos: porque diabos o Compilador não fez o uso apenas dos 8 bits do "-1" (que seria 0xFF)? ou seja, porque ele não fez um casting automático?
Ao invés, ele pegou o "-1" como sendo 0xFFFFFFFF (ou seja, usando o "long", 32 bits), por mais absurdo que pareça. Mas por que isto?
Então a resposta é: porque "eles" querem que nós façamos isto:
//--------------------------------------------------
#define menos_um -1
byte TESTE = (byte) menos_um;
//--------------------------------------------------
Seria apenas pra nos irritar?
Como diz meu Pai, "é dose", mas temos que engolir (viva Zagalo!!!).
Abrçs
Elcids
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por