Logo Hardware.com.br
jpc777
jpc777 Veterano Registrado
839 Mensagens 66 Curtidas

Campo de bit

#1 Por jpc777 04/03/2007 - 13:10
Pessoal, fiz al gumas pesquisas e descobri o seguinte:"Complemento a dois = É o operador metemático de negação, ex: x = -z*y;Complemento a um = Geralmente é usado junto com os demais operadores" lógicos.Gostaria de confirmar a seguine dedução:a) Complemento a dois coloca a penas um sinal negativo na sequencia de bits, que será representado pelo numero 1 (um). Correto ?b) Não entendi muito bem a definição de complemento a dois dada pela pela definição. Pelo que pude apurar, complemento a dois faz a inversão dos bits, certo ?C) Logo apesar dos termos complemento a um e a dois não seriam operações inversasOBS1 Estou abrindo novo tópico por orientação do forum.OBS2: Ao abrir este tópico não consegui ativar um icone.Obrigado
Fergo
Fergo Highlander Registrado
9.3K Mensagens 1.1K Curtidas
#2 Por Fergo
04/03/2007 - 13:23
Complemento de 2 é usado para tratar dos numeros negativos. É usado o bit mais significativo para tratar do sinal ( o bit mais da esquerda ). Se ele for 1, o número é negativo, se for zero é positivo.

Por exemplo, vamos escrever o numero 5 e o -5.
O número 5, em binário, é representado assim:

0101 = 0 + 4 + 0 + 1 = 5

Para pegar a forma desse numero negativo, tem um macete, que é inverter os bits e somar 1. Então o núermo 0101 vira 1010. Somando 1 se torna 1011.
Como agora o primeiro bit denota sinal negativo, fica:

1011 = - 8 + 0 + 2 + 1 = -5

Claro que pelo metodo de complemento de 2 voce perde o ultimo bit, ou seja, um byte vai de -128 até 127, caso voce use um byte sinalizado ( char ). Se voce declara um "unsigned char", ele vai de 0 a 255.
A fórmula correta para calcular um número positivo em complemento de 2 ( daí que vem o macete ) é 2^(R-1)-1, onde R é o numero de bits da palavra que voce está trabalhando.

Espero ter ajudado.

Fergo
Site pessoal www.fergonez.net
Portfolio
www.fbirck.com
Artigos
Informática
Fergo
Fergo Highlander Registrado
9.3K Mensagens 1.1K Curtidas
#4 Por Fergo
04/03/2007 - 14:16
itoa() converter um numero inteiro em uma string. Se voce fizer "valor1 & valor2", voce vai estar realizando um AND bit a bit ( se e somente se os 2 bits forem 1, resulta em 1 ):


Ex: 5 & 3 = 0101 & 0011 = 0001 = 1

O "~" representa NOT. Ele inverter os bits. Usando o mesmo exemplo acima para calcular "valor1 & ~valor2" voce vai ter

Ex: 5 & ~3

5 = 0101
3 = 0011
~3 = 1100

5 & ~3 = 0101 & 1100 = 0100 = 4


Fergo
Site pessoal www.fergonez.net
Portfolio
www.fbirck.com
Artigos
Informática
jpc777
jpc777 Veterano Registrado
839 Mensagens 66 Curtidas
#5 Por jpc777
09/03/2007 - 15:33
você teria ou poderia me dizer onde baixar uma boa apostila que tratasse de operações com números binários e hexadecimais (em português) ?O que você está fazendo para postar corretamente suas measses. Depois que o forum passou por essa atualização tenho tido dificuldades. Estou usando Windows98 com Internet explore versão de atualização sp1; precisaria e alguma atualização no IE ?Obrigado.
jqueiroz
jqueiroz Cyber Highlander Registrado
104K Mensagens 5.7K Curtidas
#6 Por jqueiroz
09/03/2007 - 17:07
O que você está fazendo para postar corretamente suas measses. Depois que o forum passou por essa atualização tenho tido dificuldades. Estou usando Windows98 com Internet explore versão de atualização sp1; precisaria e alguma atualização no IE ?Obrigado.

jpc, tente instalar o Firefox...
"chmod 777 nunca ajudou ninguém" (c) 2002-2021 JQueiroz/FGdH
Conheça o Blog do Zekke
jpc777
jpc777 Veterano Registrado
839 Mensagens 66 Curtidas
#8 Por jpc777
15/04/2007 - 09:11
nao_sei.gif

Recebi este programa de um amigo. Ele está funcionando redondinho. Mas eu gostaria de entender melhor sua lógica.

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

int agnerStrLen(char* str);
int main()
{
char a[30]= "casa";
int comprim =0;

comprim=agnerStrLen(a);
printf ("O comprimento e: %d\n ", comprim);
system ("pause&quot;
return(0);
}
int agnerStrLen(char* str)
{
int* tmp = (int*)((int) str & -4);
int durty = -1 << (((int) str - (int) tmp) << 3);
unsigned int res = 0;
int ret = 0;
if(!(res = (0x80808080 & durty & ~(*tmp) & (*tmp - 0x01010101))))
do{tmp++;}while(!(res = (0x80808080 & ~(*tmp) & (*tmp - 0x01010101))));
ret = (int) tmp - (int) str;
if(!(res & 0x8080))
{
res >>= 16;
ret += 2;
}
if(!(res & 0x80))
ret += 1;

return ret;
}



O resultado ficou:

O comprimento é 4
Pressione qualquer tecla para continuar...


Dá observação da rotina, surgiram algumas dúvidas:

1- na linha:

int* tmp = (int*)((int) str & -4);


Entendi, que se está declarando uma variável que parece fazer um duplo cast - (int*)((int) – achei estranho, nunca vi isso, só vi coisa parecida quando se passa função como argumento.

1.1 - Entendi, que “str” é parâmetro da função mas não entendi o ‘& ‘ de bit –4

2- Na linha:

i
nt durty = -1 << (((int) str - (int) tmp) << 3);


Não entendi a lógica desse deslocamento de bit, só sei, que se eu deslocar 1 a esquerda é como multiplicar por dois (ou quase)

3 – na linha:

if(!(res = (0x80808080 & durty & ~(*tmp) & (*tmp - 0x01010101))))


O que esse numero hexadecimal representa , e faz com estes vários “&”s de bit e o complemento a um ?


4 - Por fim algum poderia me indicar uma boa apostila de C++ e/ou java

Obrigado
jqueiroz
jqueiroz Cyber Highlander Registrado
104K Mensagens 5.7K Curtidas
#9 Por jqueiroz
16/04/2007 - 18:44
int* tmp = (int*)((int) str & -4);

str é um ponteiro. Para poder fazer uma operação aritmética com ele, é preciso convertê-lo em inteiro.

-4 == 0x1111.1111.1111.1111.1111.1111.1111.1100 (32 bits)

((int)str) & -4 -> apagar os 2 bits menos significativos do endereço.

Parece que a intenção de quem fez isso é forçar o alinhamento do ponteiro com uma fronteira de palavra de 32 bits.

Em seguida, ele pega o resultado, que é um valor inteiro, e converte em um ponteiro para inteiros.

int durty = -1 << (((int) str - (int) tmp) << 3);


-1 == 0x1111.1111.1111.1111.1111.1111.1111.1111 (32 bits 1).

((int)str - (int)tmp) << 3 --> ele pega a diferença entre os ponteiros, e multiplica por 8. Veja que essa diferença deve ser 0,1,2 ou 3, de acordo como "tmp" foi criado. Então o resultado desse lado da conta tem que dar 0, 8, 16 ou 24.

Acredito que a intenção aqui foi criar uma máscara de bits para isolar bytes da palavra.

if(!(res = (0x80808080 & durty & ~(*tmp) & (*tmp - 0x01010101))))

Quando ele faz " & durty" ele está usando a máscara que criou aí acima, de forma que apenas os bytes que interessam entram na conta.

*tmp - 0x01010101 --> Não tenho a mínima idéia do motivo dele ter feito isso. Deve ser alguma coisa do enunciado do problema.

Agora, uma coisa interessante... ele usou a construção:

if (condição)
do {
comandos
} while (mesma-condição);


Ele poderia ter usado, ao invés disso, a construção:

while (condição)
comandos
"chmod 777 nunca ajudou ninguém" (c) 2002-2021 JQueiroz/FGdH
Conheça o Blog do Zekke
jackinabox
jackinabox Veterano Registrado
1.1K Mensagens 8 Curtidas
#10 Por jackinabox
16/04/2007 - 21:05
jqueiroz disse:
*tmp - 0x01010101 --> Não tenho a mínima idéia do motivo dele ter feito isso. Deve ser alguma coisa do enunciado do problema.

Está subtraindo 1 de cada byte. Esse algoritmo é um strlen otimizado, que analisa 4 bytes de cada vez, até encontrar um byte zero. Em assembly faz mais sentido.
Jeferson Charles Mayer

"Como é que eu vou enxergar a tal floresta, com todas essas árvores atrapalhando a visão?"
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal