Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #57 da revista programar. Faz já o download aqui!

AngusYoung

Problema com conversor binário

Mensagens Recomendadas

AngusYoung    5
AngusYoung

Estava eu a programar o meu conversor binário, todo entretido, quando tive uma dúvida e fui ao google. Acontece, então, que encontrei isto:

public static void main(String args[]) throws Exception{
		       BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		        System.out.println("Enter the binary value:");
		         String s = br.readLine();
		        System.out.println("Decimal value is : "+Integer.parseInt(s, 2));

  Eu não acredito. Tanto tempo a escrever um programa para converter o binário, e esta "querida pessoa" (que merece levar com uma panela na testa) faz um programa que faz tudo certinho (que o meu ainda não fazia, dava o resultado ao contrário), em tão poucas linhas.

  É que é desta que eu vou para a reforma.

Alguém me explica como é que o código acima funciona, e, já agora, como imprimir uma variável ao contrário? (por exemplo, 1101 ficaria 1011)

  Obrigado desde já,

    Angus

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

Pois.. o que eu estou a fazer é "reinventar" o parseInt (neste caso) :

public void getDecimal(){

	Scanner teclado = new Scanner(System.in);
	System.out.println("Insira um bit por linha, insira 5 quando terminar");

    int sobre = 0;
    double input = 0;
    int total = 0;

    while(input != 5){
		 input = teclado.nextInt();

		 if(input == 1){
			 input = java.lang.Math.pow(2,sobre);
			 total += input;
		 }sobre++;
		 }
	System.out.println("O equivalente décimal é: " + total);

	}

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
pmg    102
pmg

Pois.. o que eu estou a fazer é "reinventar" o parseInt (neste caso) :

public void getDecimal(){

	Scanner teclado = new Scanner(System.in);
	System.out.println("Insira um bit por linha, insira 5 quando terminar");

Para introduzires 2 (10 em binario, ou 00010?) o que e que metes?

Se meteres 0 1 0 0 0, suponho que o resultado final seja 2.

Sugestao: comeca com sobre = 4 e vai reduzindo dentro do ciclo.

Sugestao numero 2: melhora a indentacao do teu codigo

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

É bem mais simples se utilizares operações binárias. À medida que o valor vai sendo inserido vais fazendo shifts ao valor final.

Depende se o número está a ser inserido da esquerda para a direita ou da direita para a esquerda.

Da esquerda para a direita:

int resultado = 0;

while (/* something */true) {
    int input; // recebe o valor do utilizador
    // valida o input
    resultado = resultado << 1 + input;
}

Da direita para a esquerda:

int resultado = 0;
int shift_num = 0;

while (/* something */true) {
    int input; // recebe o valor do utilizador
    // valida o input
    resultado = input << shift_num + resultado;
    shift_num++;
}

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

É bem mais simples se utilizares operações binárias. À medida que o valor vai sendo inserido vais fazendo shifts ao valor final.

Depende se o número está a ser inserido da esquerda para a direita ou da direita para a esquerda.

Da esquerda para a direita:

int resultado = 0;

while (/* something */true) {
    int input; // recebe o valor do utilizador
    // valida o input
    resultado = resultado << 1 + input;
}

Da direita para a esquerda:

int resultado = 0;
int shift_num = 0;

while (/* something */true) {
    int input; // recebe o valor do utilizador
    // valida o input
    resultado = input << shift_num + resultado;
    shift_num++;
}

Dá-me este erro:

  The operator << is undefined for the argument type(s) double, int

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

Continua na mesma. O código está assim:

import java.util.Random;
import java.util.Scanner;
import java.lang.Math;

public class potatoes {

public void getDecimal(){

	Scanner teclado = new Scanner(System.in);
	System.out.println("Insira um bit por linha, insira 5 quando terminar");

    int sobre = 0;
    int input = 0;
    int resultado = 0;
    int shift_num = 0;

    while(input != 5){
		 input = teclado.nextInt();

		 if(input == 1){
			 resultado = input << shift_num + resultado;
			    
		 }
		 shift_num++;
	}
    System.out.println("O equivalente décimal é: " + resultado);

}}

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

Isso é porque estás a inserir o número da esquerda para a direita e a utilizar o algoritmo que calcula o valor para uma leitura da direita para a esquerda. Eu tinha referido isso quando apresentei os dois algoritmos :(

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

Agora o resultado é sempre 0  :(

O código é este:

public void getDecimal(){

	Scanner teclado = new Scanner(System.in);
	System.out.println("Insira um bit por linha, insira 5 quando terminar");

    int sobre = 0;
    int input = 0;
    int resultado = 0;

    while(input != 5){
		 input = teclado.nextInt();

		 if(input == 1){
			 resultado = resultado << 1 + input;
			    
		 }
	}
    System.out.println("O equivalente décimal é: " + resultado);

}}

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

Não achas que a tua validação de números binários está errada? Vou dar-te uma pista: binário significa que há dois números que são válidos.

Outro problema, fui eu que te induzi em erro. O operador + tem precedência sobre o <<, logo tens que colocar a expressão entre parentesis:

resultado = (resultado << 1) + input;

Basicamente, o que esse algoritmo faz é utilizar operações sobre bits directas. À medida que vais dando valores no input, o resultado vai empurrando os bits para a frente. Para o caso em questão, aquilo que acontece (assim que corrigires o código) é o seguinte (imaginando que um int são 8 bits):

input <- 0
resultado = 00000000 + 0;

input <- 1;
resultado = 00000000 + 1 = 00000001; //ou seja, 1

input <- 0;
resultado = 00000010 + 0; // ou seja, 2

input <- 0;
resultado = 00000100 + 0; // ou seja, 4

O operador << é um shift left, ou seja, empurra os bits para a esquerda o número de casas que dizes a seguir. No caso desse algoritmo é 1.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

Eu devo estar a baralhar em alguma coisa. Continua a dar resultados que não têm nada a ver.

public void getDecimal(){

	Scanner teclado = new Scanner(System.in);
	System.out.println("Insira um bit por linha, insira 5 quando terminar");

    int sobre = 0;
    int input = 0;
    int resultado = 0;

    while(input != 5){
		 input = teclado.nextInt();

		 if(input == 1){
			 resultado = (resultado << 1) + input;
			    
		 }
	}
    System.out.println("O equivalente décimal é: " + resultado);

}}

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

Não achas que a tua validação de números binários está errada? Vou dar-te uma pista: binário significa que há dois números que são válidos.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

Sim. Mas, acho que não ficaste completamente esclarecido, não sei exactamente porquê... :(

Basicamente o que tens que fazer é alterar o if para incluir a introdução de zeros:

if (input == 1 || input == 0)

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

Eh pa, eu sou mesmo cromo. Fui ao programa e meti isso, mas com && em vez de ||. Tive lá um pouco de tempo a ver porque é que o total era sempre 0  :):D:)

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

Ok:

Já estou a fazer a parte decimal -> binário. Andei a pesquisar, e como a length dos arrays não é dinâmica, estou a usar um arrayList.

O problema é que voltei ao problema inicial. Ao imprimir o arrayList, queria que imprimisse ao contrário, e arranjei uma maneira só que estou com um probleminha - primeiro o código:

public void getBin(){
 System.out.println("Insira o número decimal");

 List<Integer> array = new ArrayList<Integer>();
 int i = 0;

 Scanner teclado = new Scanner(System.in);
int binput = teclado.nextInt();

while(binput != 0){
	array.add(i,binput % 2);
	binput /= 2;
	i++;

} //fim do while

int counter = array.size();


while(counter != 0){                       //AQUI QUERIA QUE FOSSE IMPRIMIDA A CASA NºCOUNTER
System.out.println(array);      //DO ARRAYLIST, E COM COUNTER-- VAI IMPRIMINDO ATÉ CHEGAR A 0
counter--;
}

O pedido está inserido como comentário no código.

Obrigado desde já,

    Angus

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
AngusYoung    5
AngusYoung

Eu já tinha feito esse código antes de o baderous postar, mas dá-me o erro:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4

at java.util.ArrayList.rangeCheck(Unknown Source)

at java.util.ArrayList.get(Unknown Source)

at potatoes.getBin(potatoes.java:50)

at mainClass.main(mainClass.java:9)

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


×

Aviso Sobre Cookies

Ao usar este site você aceita a nossa Política de Privacidade