Duvida básica Double

Seguinte,
tou com um problema usando o tipo primitivo double.

se eu atribuo por exemplo 400.50 num atributo double (tpw primitivo)
e depois uso ele para subtrair 200.30 por exemplo
ao invéz de ele ficar com 200.20
ele fica com 200.19999999.

porque disso?
obrigado.

Nunca tinha testado isso!

ta ai boa dúvida!

[quote=mokuro]Seguinte,
tou com um problema usando o tipo primitivo double.

se eu atribuo por exemplo 400.50 num atributo double (tpw primitivo)
e depois uso ele para subtrair 200.30 por exemplo
ao invéz de ele ficar com 200.20
ele fica com 200.19999999.

porque disso?
obrigado.[/quote]

:? estranho. Testei aqui em casa e está tudo normal

   [code]double d1=400.50;
    double d2 =200.30;
    System.out.println(d1-d2);[/code]

retornou: 200.2

Também testei e foi normal…

double x = 400.5; x -= 200.3; System.out.println(x);

[quote=mokuro]Seguinte,
tou com um problema usando o tipo primitivo double.

se eu atribuo por exemplo 400.50 num atributo double (tpw primitivo)
e depois uso ele para subtrair 200.30 por exemplo
ao invéz de ele ficar com 200.20
ele fica com 200.19999999.

porque disso?
obrigado.[/quote]

Isso pode ser explicado pelo erro na precisão do cálculo dos números de ponto flutuante. Leia sobre a keyword strictfp
http://en.wikipedia.org/wiki/Strictfp

Lembro-me que uma vez o Vini falou sobre esse assunto no GUJ, mas não encontrei o tópico

Ok, dei uma resumida nas classes pra deixar soh a parte que realmente interessa, que é este double.

nesse código eu entro com 1 valor do teclado pelo Scanner para fazer o cálculo de subtração do Scanner
coloquei 1 valor fixo de 400.50.

ao rodar esse progrmaa, se eu ponho por exemplo 200.30 pra ele diminuir ele me traz como resultado 200.1999999999999999.

aproveitando pra fazer outra pergunta, como da pra ver no meu Scanner eu coloquei um “.next();”. Motivo: ele me da um Exception java.util.InputMismatchException se eu entro com um valor como 400.50 por exemplo,utilizando o .nextDouble(); então fiz a gambiarra ali do parseDouble, mas ele nao deveria aceitar um 400.50 no .nextDouble(); da classe Scaner? obrigado

public class View {
	Scanner scan = new Scanner(System.in).useDelimiter("\r\n");
	ContaCorrente cc = new ContaCorrente();
	private int numAgencia;
	private int numConta;
	private double valor;

public void execSaque() {
		cc.setSaldo(400.50); //Exemplo especifico para o fórum
		leValores();
		cc.sacar(this.valor);
	}

public void leValores() {
		System.out.print("Valor: ");
		this.valor = Double.parseDouble(this.scan.next());
	}
}
public class ContaCorrente {
	private int numAgencia;
	private int numConta;
	private String nome;
	private double saldo;

	public int sacar(double pValor) {
		if (this.saldo < pValor) {
			System.out.println("Saldo Insuficiente");
			return 0;
		} else {
			this.saldo = this.saldo - pValor;
			System.out.println("Saque realizado com sucesso");
			return 1;
		}
	}

Ok, consegui resolver o problema do .nextDouble(); do Scanner utilizando :

scan.useLocale(Locale.US);

mesmo os valores sendo atribuidos com um ponto (xx.xx), ele tentava pegar com vírgula (xx,xx) por algum motivo.

ainda sim, o problema do valor errado na precisão do cálculo do double persiste.
alguma luz?
obrigado

Nossa amigo, uma vez eu li um material tao bom sobre o assunto, que pena nao lembrar aonde eu vi. Apenas lembro que é um site relacionado a java web.

O tutorial ate trazia um exemplo bem interessante. E dizia para usar uma API do java que trabalha com double, que no momento nao estou lembrado.

De uma procurada ai e se achar algo, poste para nos.

Editado:
Bem, achei! :slight_smile:

Nada que uma gloogada nao resolva. Veja o link:

http://www.j2eebrasil.com.br/mostrar/47

Abraços

[quote=blackfalcon]Nossa amigo, uma vez eu li um material tao bom sobre o assunto, que pena nao lembrar aonde eu vi. Apenas lembro que é um site relacionado a java web.

O tutorial ate trazia um exemplo bem interessante. E dizia para usar uma API do java que trabalha com double, que no momento nao estou lembrado.

De uma procurada ai e se achar algo, poste para nos.

Editado:
Bem, achei! :slight_smile:

Nada que uma gloogada nao resolva. Veja o link:

http://www.j2eebrasil.com.br/mostrar/47

Abraços[/quote]

Hum, excelente artigo!!

mas ainda sim, um long não se pode usar casas decimais com virgula, então o esquema é usar este BigDecimal.

mas acredito que exista outras maneiras de trabalhar com double ou até mesmo um Integer utilizando casas com virgulas. vou pesquisar sobre. até lá fico no BigDecimal

obrigado!!

[quote=mokuro]Seguinte,
tou com um problema usando o tipo primitivo double.

se eu atribuo por exemplo 400.50 num atributo double (tpw primitivo)
e depois uso ele para subtrair 200.30 por exemplo
ao invéz de ele ficar com 200.20
ele fica com 200.19999999.

porque disso?
[/quote]

Porque nem todos os numeros são representáveis em double. Isso é uma surpresa para si ? Então deixe de usar double :slight_smile:
Qualquer potencia negativa de 10 não é representável em double.
A diferença entre os numeros é 0.10 que é uma potencia negativa de 10, logo não é representável corretamente.

outro problema com double é o uso dos operadores > , < , <=, >= e == Estes operadores não funcionam corretamente para doube
e não devem ser usados sem saber o que se está fazendo.

Usar double é mais complexo do que parece. Vc apenas deve usar double se vc entende como ele funciona. Se vc não entende, não use.
Use BigDecimal em vez, ou no caso de dinheiro use o padrão Money.

Como regra não use double, nunca. Use sempre BigDecimal para numeros decimais.

++
E acrescento: isso vale pra float tbm :wink: