• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Gurzi

[Resolvido] Binário para decimal

9 mensagens neste tópico

Bem estava aqui a tentar fazer uma conversão de binário para decimal, fiz este código mas não dá, alguem que possa ver a lógica? onde errei ?

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

int elevado(int x, int y)
{
    
    int g=0;
    while (g >=y-1)
    {
    x*=x;
    y++;
    }
    return x;
}

int main(){

    int a = 0;
    char text[10];
    int k=0;
    int total=0;

printf("introduza um numero\n");
scanf("%d",&a);
sprintf(text, "%d", a);
int i=strlen(text);
while (i != 0)
{
total += text[i]*(elevado(2,k));
k++;
i--;
}
printf("%d\n", total);
system("PAUSE");
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

é só para lembrar que já debateu sobre o assunto nesta secção!! gurzi procura o código...ok que é para resolver o erro do teu programa...mas estou alerta para não termos 2 topicos sobre o mesmo na mesma secção!!!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
//int elevado(int x, int y)
int elevado(int y)
{    
    /*int i,g=1;       // axo k era melhor usar o shift logico como tem abaixo, 
    for (i=0;i<y;i++)  // de qualquer forma esta' aqui uma possivel solucao 
        g*=x;    
    return g;*/
    if (y==0)
       return 1;
    else
        return 2 << (y-1);    //  "<<" e' o shift logico 'a esquerda o que significa multiplicar por 2. 
                             // como neste caso 'x' e' sempre 2, nao penso que ha necessidade 
                             // de o colocar como parametro.
}                          //  deslocar 2,  (y-1) vezes para a esquerda equivale a fazer 2^y

int main(){ 
    int a = 0;
    char text[10];
    int k=0;
    int total=0;
   
    printf("introduza um numero\n");
    scanf("%d",&a);
    sprintf(text, "%d", a);
    int i=strlen(text)-1;    // o ultimo digito do numero está em   strlen(text) - 1  ... 
    while (i >=0)        // importante nao esquecer que a contagem começa em 0.
     {
         total += (text[i]-'0') * (elevado(k)); //  text[i] tem o valor ascii do '0' ou '1'...                                             
         k++;                     //o que nao e' igual a 0 e 1... para obter os numeros 
         i--;                        // subtraimos o valor ascii do '0'...   '1' = '0' +1
    }
    printf("%d\n", total);
    system("PAUSE");
    return 0;
}

cumprimentos  :ipool:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mogers muito obrigado, parece que não andei muito longe da formula correcta, acontece que é a primeira vez que estou a ouvir falar do << " li o que disseste mas não entendi bem , podias explicar melhor por favor ?

    if (y==0)

      return 1;

    else

        return 2 << (y-1);    //  "<<" e' o shift logico 'a esquerda o que significa multiplicar por 2.

                            // como neste caso 'x' e' sempre 2, nao penso que ha necessidade

                            // de o colocar como parametro.

}                          //  deslocar 2,  (y-1) vezes para a esquerda equivale a fazer 2^y

também não entendi isto :

        total += (text-'0') * (elevado(k)); //  text tem o valor ascii do '0' ou '1'...                                           

        k++;                    //o que nao e' igual a 0 e 1... para obter os numeros

        i--;                        // subtraimos o valor ascii do '0'...  '1' = '0' +1

quer dizer, já percebi, agora não percebo é o porque de -'0' e não -'1' ou outro número qualquer

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Cheguei a fazer código para isso para um problema que tinha saído também nas olimpíadas da física, não precisei de mais de 15 linhas de código...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mogers muito obrigado, parece que não andei muito longe da formula correcta, acontece que é a primeira vez que estou a ouvir falar do << " li o que disseste mas não entendi bem , podias explicar melhor por favor ?

Isto tem a ver com binario mesmo. Em binario para multiplicar por 2, basta acrescentar um zero à direita do número, ou seja:

1:  0001

2:  0010

4:  0100

8:  1000

etc

Isto é chamado um shift logico 'a esquerda. Logico porque não preserva o sinal (em binario, o bit mais significativo [akele mais a esquerda] e' o bit de sinal 0 -> positivo, 1 -> negativo), no caso do 8: se considerassemos o sinal estavamos perante um numero negativo. O shift consiste em deslocar os bits para a esquerda e acrescentar um zero.

Só funciona assim neste caso, devido a estarmos a multiplicar por 2.

Sintaxe:      numero << numero_de_vezes_a_deslocar;

Exemplo:  3 << 4;  é a mesma coisa que fazer  3 * 2 * 2 * 2 * 2

Existe o oposto, o shift à direita com o operador ">>" ... de modo analogo, em vez de multiplicar, divide por 2.

Sintaxe:    numero >> numero_de_vezes_a_deslocar;

Exemplo:  medio = ( numA + numB) >> 1;      -->  mesmo que  ( numA + numB) / 2

Nao sei se deu para perceber que e' mais eficiente, visto que na pratica nao e' feita qualquer multiplicacao. E' apenas "ligar os fios" como o meu prof diz. Deslocar os bits e acrecentar um bit a zero.

Se nao consegui explicar bem, avisa  :hmm:

também não entendi isto :

        total += (text[ i ]-'0') * (elevado(k)); //  text[ i ] tem o valor ascii do '0' ou '1'...                                           

        k++;                    //o que nao e' igual a 0 e 1... para obter os numeros

        i--;                        // subtraimos o valor ascii do '0'...  '1' = '0' +1

quer dizer, já percebi, agora não percebo é o porque de -'0' e não -'1' ou outro número qualquer

Já experimentaste fazer o seguinte?

printf("%d %d\n" , 'A' , 'B' );
printf("%d %d\n" , '0' , '1' );

Isto vai imprimir o codigo ASCII dos caracteres. Como podes verificar, o código ASCII do 'B' é o codigo imediatamente a seguir ao do 'A', da mesma forma o '1' esta a seguir ao '0'. Tanto as letras do alfabecto como os digitos de 0 a 9 estao seguidos.

Ao fazeres  total += text[ i ] * (elevado(k))  estas a multiplicar o codigo ASCII do caracter  text[ i ] pelo valor retornado pela funcao "elevado". Como o codigo ASCII do '0' nao corresponde a zero (e' igual a 48 por curiosidade), como estas a ver nao estas a fazer a multiplicacao de que pretendes.

Para se perceber melhor imprimi os codigos ASCII dos digitos:

'0' = 48

'1' = 49

'2' = 50

'3' = 51

etc

Com a instrucao  (text[ i ]-'0')  vais subtrair ao codigo ASCII do  text[ i ] o codigo do '0' que e' 48. Neste caso o caracter text[ i ] so' pode ser '0' ou '1'. Sendo assim:  '0' - '0' = 0      e    '1' - '0' = 1    com esta subtraccao ja' tens os valores decimais do 0 e do 1 correctos.

Espero ter sido claro... critiquem o post  :D

Offtopic: Há alguma opcao de modo a nao interpretar o "[ i]" (sem o espaco)  como italico? Alem de nao me reconhecer caracters acentuados e "c" com cedilha... desculpem mas tou sem tempo para procurar isso..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mogers, adorei o post, tens uma grande paciência , fico grato por isso, percebi muito bem a parte do ASCII e esse pensamento é muito á frente , nunca me ia passar isso pela cabeça lol.. em relação aos bits ele multiplica e divide sempre por 2 ??

vou ler mais informação na net, porque confesso que de binários, pouco sei, por issso estou verde nisto :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sempre às ordens (quando há tempo)  :D

mogers, adorei o post, tens uma grande paciência , fico grato por isso, percebi muito bem a parte do ASCII e esse pensamento é muito á frente , nunca me ia passar isso pela cabeça lol.. em relação aos bits ele multiplica e divide sempre por 2 ??

Os computadores funcionam em binario, por isso é sempre por 2.

Eu também nunca tinha pensado naquilo do ASCII até ver um código dum rapaz em que usava isso.

Offtopic (espero que nao se importem):

Quando lemos um texto, caracter a caracter, para verificar se o caracter actual era uma letra do alfabecto, eu criava uma string com o alfabecto e ia procurar o caracter no alfabecto. Contudo basta:

char  c = getchar();
while (c!=EOF)
{
     if ( ( c >= 'A' ) && ( c <= 'Z' ))  // este codigo passa as letras maiusculas para minusculas
           c = c - 'A' + 'a'; 

     if ( ( c >= 'a' ) && ( c <= 'z' ))  //   c pertence ao alfabecto
     {
              // o que quisermos
      }
     c = getchar();
}

muito mais simples... não sei se já tinham pensado nisto.

cumps  :ipool:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

vou cagar agora nisso do shift à esquerda porque sinceramntenão estou a perceer muito bem , whatever,fica a tua boa ajuda

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora