ERRO - possible loss of precision

Olá pesoal !
Ainda sou iniciante em JAVA, já postei aqui um dúvida e fui muito bem atendido, espero ser novamente.
Bem, sempre tento resolver os problemas com meus códigos sem precisar perguntar aqui, acredito que assim o aprendizado torna-se mais eficaz. Porém, estou tendo um problemão com um código.
Já fiz todos os exemplos do livro do Sérgio Fuirgeri que trata do pacote Swing. Também já fiz os exercícios, mas deixei esse aqui por último por acreditar que seria mais fácil, mas está dando uns erros que não consigo enxergar a solução, mas que parece de fácil resolução.

O exercício pede para que entremos com um valor em um campo JTextField (t1), selecionar uma forma de pagamento com um elemento JRadioButton e, dependendo da escolha, mostrar o resultado num elemento JTextField (t2). Se a escolha for pagamento em dinheiro, dar 5% de desconto, se for cheque, acréscimo de 5%, se for cartão, acréscimo de 10%.

Bem, o código é o seguinte

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Exercicio0907 extends JFrame implements ItemListener
{
	float n1 = 0, result = 0;
	JLabel label1, label2;
	JTextField t1,t2;
	JRadioButton radio1,radio2,radio3;
	JPanel p1,p2,p3;
	ButtonGroup radiogroup;
	
	public static void main (String args[])
	{
		JFrame janela = new Exercicio0907();
		janela.setUndecorated(true);
		janela.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
		janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		janela.setVisible(true);
	}
	
	Exercicio0907()
	{
		setTitle("Cálculo do Preço Final");
		setBounds(230,50,340,120);
		getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
		label1 = new JLabel("Digite o valor da venda");
		label2 = new JLabel("Preço final de venda");
		t1 = new JTextField();  t1 = new JTextField();
		p1 = new JPanel(); p2 = new JPanel(); p3 = new JPanel();
		radio1 = new JRadioButton("Dinheiro");
		radio2 = new JRadioButton("Cheque");
		radio3 = new JRadioButton("Cartão");
		radiogroup = new ButtonGroup();
		radiogroup.add(radio1); radio1.addItemListener(this);
		radiogroup.add(radio2); radio2.addItemListener(this);
		radiogroup.add(radio3); radio3.addItemListener(this);
		p1.setLayout(new GridLayout(1,2));
		p1.setBackground(new Color(65,105,225));
		p2.setLayout(new GridLayout(1,3));
		p2.setBackground(new Color(0,255,225));
		p3.setLayout(new GridLayout(1,2));
		p3.setBackground(new Color(0,255,255));
		p1.add(label1); p1.add(t1);
		p2.add(radio1); p2.add(radio2); p2.add(radio3);
		p3.add(label2); p3.add(t2);
		getContentPane().add(p1); getContentPane().add(p2);
		getContentPane().add(p3);
    }
    
    public void itemStateChanged(ItemEvent e)
    {
    	if(t1.getText().length()==0) return;
    	try
    	{
    		n1 = Float.parseFloat(t1.getText());
    		if(e.getSource()==radio1) result = n1*0.95;
    		if(e.getSource()==radio2) result = n1*1.05;
    		if(e.getSource()==radio3) result = n1*1.10;
    	}
    	catch(NumberFormatException erro)
    	{
    		t2.setText("Erro!!"); return;
    	}
    	t2.setText("" + result);
    }
}

Os erros estão ocorrendo nas linhas 58, 59 e 60 e cada vez que eu tento resolver o problema mudando o código dá um erro diferente.

Agora o erro que está dando é:

[color=red]possible loss of precision[/color]

O estranho é que nas primeiras vezes que tentei compilar dava erros avisando que faltava um parenteses. Aí eu mudava e dava erro dizendo que faltava um ponto e vírgula. Mudava as variáveis n1 e result para Double e dava imcompatible types.

O mais estranho ainda é que esse exercício foi feito baseado num exemplo do próprio livro que funcionou muito bem.

Bem, e então, algum anjo aí pode me dar essa mão? Sei que a dúvida é básica, sei que o problema está fácil de ser resolvido, mas já tentei de todas as formas resolvê-lo e não consegui.

Se possível também coloquem um link aí onde eu possa pegar uma listagem dos erros em JAVA e suas possíveis causas, assim eu poderia estudá-las e não perturbar mais com essas dúvidas por aqui.

Obrigado aí, pessoal.

Olá Valder !!!

esse erro é erro de precisão tenta mudar o tipo dessa sua variavel result, pois o cálculo deve esta retornando uma valor que não cabe em uma variavel do tipo float;

Não tenho certeza, pois este horário não é muito bom para pensar, mais tenta ai que eu tenho quase certeza que seja isso.

Bom divertimento…

tente fazer comparação utilizando equals(“String”);

eu não trabalho com swing, c for necesario parse faça ai…

  if(e.getSource().equals(radio1) result = n1*0.95;  

É um aviso dizendo que você pode perder um pouco da precisão dos valores devido à quantidade menor de casas decimais que as variáveis float armazenam.

Se você quer manter assim mesmo, experimente explicitar a sua escolha, fazendo assim em valores float puros:

float n1 = 0f, result = 0f;

Viu? Basta colocar um f no final do número.

viajei…isso q dá passar noite trabalhando…

au adicione f no final da atribuição, ou declare como um double (double result)…

abs !!

Olá, pessoal, muito obrigado pela ajuda, mas o problema persiste.
Bem, atendendo o conselho do SBguimaraes, troquei a variável result para double e deu o seguinte erro:

--------------------Configuration: --------------------
Exception in thread “main” java.lang.NullPointerException
at java.awt.Container.addImpl(Container.java:1031)
at java.awt.Container.add(Container.java:352)
at Exercicio0907.(Exercicio0907.java:48)
at Exercicio0907.main(Exercicio0907.java:17)

Como disse no primeiro post, já havia tentado trocar a variável para double, mas deu esse problema aí mesmo.

Usando equals, como o sou daniel aconselhou, ocore o mesmo problema, porém onde está escrito Exercicio0907.vaja:48 ele muda o último número para 47 e na linha seguinte para 16, vejam:

--------------------Configuration: --------------------
Exception in thread “main” java.lang.NullPointerException
at java.awt.Container.addImpl(Container.java:1031)
at java.awt.Container.add(Container.java:352)
at Exercicio0907.(Exercicio0907.java:47)
at Exercicio0907.main(Exercicio0907.java:16)

Seguindo o conselho do Yky Mattshawn, coloquei um f após o valor da inicialização das variáveis, mas deu o mesmo problema de possible loss of precision.

O problema é que essas tosqueiras de erros já deram aqyui e resolvi na boa ! Mas agora encrencou de vez.
Bem, podem continuar ajudando ? Hehehe !!

Eu vou refazer todo o exercicio, mas utilizando outro código diferente, pois estou desconfiado de que o problema possa ser na colocação dos elementos JRadioButton nos painéis.

De mais, obrigado pela atenção de vocês !

Tente isso!
aki resolveu…aparentente :smiley:

              n1 = Float.parseFloat(t1.getText());  
              if(e.getSource()==radio1) result = (float)(n1 * 0.95);  
              if(e.getSource()==radio2) result = (float)( n1 * 1.05);  
               if(e.getSource()==radio3) result =(float)(n1 * 1.10);

[quote=soudaniel_01]ou declare como um double (double result)…

abs !![/quote]

double n1 = 0, result = 0;

Tmb aki encerrou o erro…tem que olhar pra ver no que isso vai refletir se tu tiveres outras classes…
espero ter ajudado…
um abraço!

Tente usar cast de float (ou double, se você acha que pode vir um int).

result = (float ) n1 * 0.95;

Ou melhor… primeiro tenta isso que vou falar pra você agora.

Em vez de

float n1 = 0, result = 0;  

Coloca

float n1 = 0.0, result = 0.0;  

Ou ainda, tenta isso também:

float n1 = 0.0f, result = 0.0f;  

Desculpa não te dar certeza… é que to no Windos e meu pc é meio ruim pra rodar java aqui :confused:

EDIT: Cássio… desculpa cara, nem tinha lido seu primeiro post (onde você usa o cast). Foi mal mesmo cara :confused: O sono tá complicado.
Abraço.

Galera, que loucura !!!

Esse código aqui funcionou sem fazer nada, absolutamente nada !!!Apenas tive que mudar as variáveis n1 e result para double.

Vejam o novo código e, poooooorrrrrr favooorrrrrrrr, me ajudeeeeeeeeeemmmmmmmmmmm. N~]ao me dou por contente, quero entender o que está provocando essas tosqueiras de erros em meu código original.

Vejam o que funcionou:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Exercicio0907_01 extends JFrame implements ItemListener
{
	double n1 = 0, result = 0;
	JLabel label1,label2;
	JTextField t1, t2;
	JPanel p1,p2;
	JRadioButton radio1, radio2, radio3;
	ButtonGroup radiogroup;
	public static void main (String args[])
	{
		JFrame janela = new Exercicio0907_01();
		janela.setUndecorated(true);
		janela.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
		janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		janela.setVisible(true);
	}	
		
		Exercicio0907_01()
		{
			setTitle("Cálculo do preço final");
			setBounds(230,50,340,120);
			getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
			label1 = new JLabel("Informe o valor da venda");
			label1.setForeground(Color.blue);
			label2 = new JLabel("Preço final da venda:");
			label2.setForeground(Color.blue);
			t1 = new JTextField(5);     t2 = new JTextField(5);
			p1 = new JPanel();           p2 = new JPanel();
			t2.setEditable(false);
			radio1 = new JRadioButton("Dinheiro");
			radio2 = new JRadioButton("Cheque");
			radio3 = new JRadioButton("Cartão");
			radio1.setMnemonic(KeyEvent.VK_1);
			radio2.setMnemonic(KeyEvent.VK_2);
			radio3.setMnemonic(KeyEvent.VK_3);
			radiogroup = new ButtonGroup();
			radiogroup.add(radio1);   radio1.addItemListener(this);
			radiogroup.add(radio2);   radio2.addItemListener(this);
			radiogroup.add(radio3);   radio3.addItemListener(this);
			p1.setLayout(new FlowLayout(FlowLayout.CENTER));
			p1.setBackground(new Color(250,250,250));
			p2.setLayout(new GridLayout(2,3));
			p2.setBackground(new Color(100,100,100));
			p1.add(label1);  p1.add(t1);  p2.add(radio1);
			p2.add(radio2);  p2.add(radio3);  p2.add(label2);  p2.add(t2);
			getContentPane().add(p1);     getContentPane().add(p2);
		}
		
		public void itemStateChanged(ItemEvent e)
		{
			if(t1.getText().length()==0) return;
			   try
			   {
			   	  n1 = Double.parseDouble(t1.getText());
			   	  if (e.getSource()==radio1) result = (n1*0.95);
			   	  if (e.getSource()==radio2) result = (n1*1.05);
			   	  if (e.getSource()==radio3) result = (n1*1.10);
			   }
			   catch(NumberFormatException erro)
			   {
			   	  t2.setText("Erro"); return;
			   }
			   t2.setText("" + result);
		}
}

Esse aí é o exercicio0910 do livro que eu adaptei para esse exercício0907. Por que com o código do autor funciona e com o meu, mais bonitinho a interface gráfica, não funciona ?

Aliás, as únicas diferenças são a troca dos tipos das variáveis para double e os setMnemonics da vida, mas isso acho que é perfumaria, poxa !

É, acho que vou largar mão disso !

Cássio, valeu pela dica, obrigado, mas deu essa mensagem seguinte:

Exception in thread “main” java.lang.NullPointerException
at java.awt.Container.addImpl(Container.java:1031)
at java.awt.Container.add(Container.java:352)
at Exercicio0907.(Exercicio0907.java:47)
at Exercicio0907.main(Exercicio0907.java:16)

dedejava, com sua dica o problema de loss of precision persiste e está na linha 7 agora. Isso mantendo os parenteses com os float no meio, como o Cássio propôs (float), antes da expressão do cálculo.

Quando eu retiro os parenteses que o Cássio propôs volta a dar loss of precision nas linhas 58, 59 e 60.

Acho que vou largar mão disso e jogar a bomba para meu professor de JAVA na facul esse ano viu.

Mas, como pode uma linguagem dar um bug tão grande e ridículo assim em ponto flutuante ?
Na boa, sou iniciante em JAVA, mas sou Físico por formação, e como tal tive que programar em algumas linguagens para os cálculos na pós graduação.

Na graduação aprendi PASCAL e alguma coisa de C. Na pós programei em MathLab, uma linguagem destinada a cálculos e simulações científicas, e em nenhuma delas havia esses bugs em ponto flutuante, nem em MathLab, que nem gera código executável e nem se compara com JAVA pela complexidade.
Também comecei a estudar Delphi, mas por orientação de algumas pessoas larguei mão e comecei a estudar JAVA por ser uma linguagem muito requisitada. Em Delphi esse tipo de problema jamais ocorreu, minha nossa !!!

Seu código original tinha um:

t1 = new JTextField();  t1 = new JTextField();

Que deveria ser:

t1 = new JTextField();  t2 = new JTextField();

Pois quando ele fosse executar:

p3.add(t2);

Ele teria uma referência para buscar. Sem inicializar, você está mandando uma referência nula e ele vai reclamar de NullPointerException.

Segundo ponto: uma multiplicação de um float por double - sim, um double. Qualquer número decimal sem identificador é considerado um double! - gera no mínimo um outro double.
Então em:

result = n1 * 0.95

ele faz: Tá, você pega um valor float (32-bits) e multiplica por um valor double(64-bits) e joga isso numa variável float(32-bits). Viu que o que ele reclama procede? Você vai perder precisão por colocar um número com representação maior do que o permitido. Para corrigir sem mudar muito seu código, é só dizer que o número decimal que você está trabalhando também é um float, como em:

result = n1 * 0.95f

Isso vai retornar no mínimo um float.

Viu? Não precisou de muitas alterações no seu código original.

Ah, e se aparecer um número estranho com muitas casas decimais, não é que Java não sabe fazer conta. É que ele respeita a IEEE-754 e isso faz com que a representação dele não seja exata. Bom artigo para se ler que já foi colocado aqui no fórum sobre isso: http://docs.sun.com/source/806-3568/ncg_goldberg.html

Até!

/
||
||
||

Esse entende e muuuiiiiiittooooooo !!!

Magnífico !!!, espetacular !!!, excepcional, maquiavelbona !!!

Esse era exatamente o problema. Agora entendo o por que dava esses problemas !!!

Muitíssimo obrigado não apenas por resolver o problema de meu código, mas muito mais pelas explicações que colocou em seu post acima, com certeza nele aprendi coisas importantíssimas para a prática de programação.
O prblema de muitas casa decimais nas respostas é facilmente resolvido com a classe DecimalFormat, certo ?

Muito obrigado aos outros também pelas dicas !

[quote=dedejava]

EDIT: Cássio… desculpa cara, nem tinha lido seu primeiro post (onde você usa o cast). Foi mal mesmo cara :confused: O sono tá complicado.
Abraço.[/quote]

Caaapaz cara nem se estresse com isso!
acontece!
:smiley:

Aaaa e verdade sr Valder Olmo Corrêa…pra mim o maquiavelbona é um computador! nao pode ser humano!
uhauhahuahuahuahuauha o cara responde todas tche! ta em todos os foruns q eu ja li!
hehehehehe!

Exelente explicação!

[quote=Valder Olmo Corrêa]…
O problema de muitas casa decimais nas respostas é facilmente resolvido com a classe DecimalFormat, certo ?
…[/quote]
Isso! E uma máscara adequada seria #,##0.00 . Dê uma olhadinha na documentação que lá tem bastante informação útil.

Estamos aí.

Até!