Ponto Flutuante

21 respostas
D

galera, eu tenho um programa, mas ele nao aceita ponto flutuante, exemplo: 12.000

Eu preciso calcular a porcentagem em cima desse numero exemplo:

valor -> 5.000 %margem -> 50 resultado -> 10.000 (nao é o valor certo, só um exemplo)

queria saber como faço pro programa aceitar os float points…

Obrigado, Danillo.

21 Respostas

darklordkamui

Utilize BigDecimal… assim vc consegue fazer mais facil essas contas

D

tem como voce me dar um exemplo de utilização cara?

al.barbosa

No link abaixo tem uma explicação de por que usar BigDecimal:

http://www.guj.com.br/java/275524-java-calculando-errado-o-valor-de-2-doubles#1448885

E neste link explica basicamente como usar:

http://blog.caelum.com.br/arredondamento-no-java-do-double-ao-bigdecimal/

Com o BigDecimal você usa métodos como add() e subtract() para realizar as operações, em vez de utilizar operadores como + e -. Você pode encontrar os métodos na API do Java SE.

javax.swing.Daniel

Danillo, tem como você postar o trecho de seu código que não está funcionando da maneira que você quer ?

D

essa é a parte do programa que faz a conta que eu quero

n1 = Integer.parseInt(t_valorfin.getText());

n2 = Integer.parseInt(t_margem.getText());

n3 = (n1 * (n2/100)) ;

t_valormargem.setText(""+n3+"");

o ‘‘t_valorfin’’ é o jTextField que eu queria que recebesse float points “12.0”

e o ‘‘t_valormargem’’ é o jTextField que vai mostrar o resultado, que eu queria que mostrasse float tamem

valeu

javax.swing.Daniel

Ao invés de utilizar Integer.parseInt(), utilize Float.parseFloat ou Double.parseDouble() para trabalhar com pontos flutuantes.
Exemplo:

double n1 = Double.parseDouble(t_valorfin.getText()); double n2 = Double.parseDouble(t_margem.getText()); double n3 = n1 * ( n2 / 100 ); t_valormargem.setText(""+n3+"");

javax.swing.Daniel

Testa esse comando de formatação de string. Isso deixará a saída mais apresentável.

t_valormargem.setText(""+ String.format("%0.2f", n3) +"");

Obs: Não me lembro se assim funciona, estou sem o java aqui para testar…

D

cara, desculpa a insistencia, mas nao rodou…

na hra de calcular ele da erro

darklordkamui

desculpa a demora em responder....

segue um exemplo

String bla = "123456.44444";
		String bl1 = "7901124.43344";
		BigDecimal CEM = new BigDecimal("100");

		BigDecimal n3 = BigDecimal.ZERO;  // inicia BigDecimal com zero
		BigDecimal n1 = new BigDecimal(bla);
		BigDecimal n2 = new BigDecimal(bl1);

		n3 = n1.multiply(n2.divide(CEM)).setScale(4, RoundingMode.HALF_UP);  // 		
		System.out.println(n3);
               /** calcula e eu estipulo quantas casas decimais quero que apareça e tenho a 
		 * possibilidade de arredondar o valor nesse exemplo para cima...
		 * saida foi [telefone removido].3051
		**/

a String bla no meu exemplo é equivalente ao que ta vindo da caixa de texto... mais cuidado isso pode dar NumberFormatException se vc nao tratar o que vem na caixa do JText =P

javax.swing.Daniel

O que você deve fazer é algo que segue o estilo abaixo:

double n1 = Float.parseFloat("150.20"); // Valor total
double n2 = Float.parseFloat("10"); // Desconto  
double n3 = n1 * ( n2 / 100 ); // Calculo do desconto
		
System.out.printf("%.2f", n3); // Valor do desconto.
al.barbosa

Danilo,

O mesmo exemplo do Daniel com BigDecimal:

BigDecimal n1 = new BigDecimal("150.20"); // Valor total  
BigDecimal n2 = new BigDecimal("10"); // Desconto    
BigDecimal n3 = n1.multiply(  n2.divide( new BigDecimal("100") ) ); // Calculo do desconto  

System.out.println(n3);    // Valor do desconto.

//não sei se da para imprimir o BigDecimal com printf(), pode testar
//System.out.printf("%.2f", n3); // Valor do desconto.
E

É por isso que o pessoal reclama que Java é complicado.
Logo de cara apresentam o rapaz ao BigDecimal, que só deve ser usado em algumas situações :slight_smile:

No caso específico que ele queria, um double é suficiente, sabendo é claro formatar o número adequadamente (normalmente, um System.out.printf ou um String.format é mais que suficiente).

D

Galera, obg msm pela ajuda, mas em cima disso…é só com valores pré definidos, ou serve pra tamem se o usuário digitar o valor?

ta me parecendo que só funciona pra valores pré definidos.

Obrigado

rmendes08

danillo.neto:
Galera, obg msm pela ajuda, mas em cima disso…é só com valores pré definidos, ou serve pra tamem se o usuário digitar o valor?

ta me parecendo que só funciona pra valores pré definidos.

Obrigado

Você deve estar digitando o valor com vírgula, aí não funciona mesmo, pois o parseDouble entende que é o ponto que separa as casas decimais.

E

Vou passar um exemplo bem estúpido (daqueles com JOptionPane - argh) que aceita valores monetários (por exemplo, 5.000,00).
Me dá 2 min

D

rmendes

nao cara…eu digito com ‘’.’’ mesmo…nao sei pq o sistema nao roda…tentei parseDouble, parseFloat…nada

q dor de cabeça esse trecho cara…

E
/**
 * 
 */
package guj;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;

import javax.swing.JOptionPane;

/**
 */
public class ExemploDecimalFormat {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Locale ptBR = new Locale ("pt", "BR");
        DecimalFormat df = new DecimalFormat ("#,##0.00", new DecimalFormatSymbols (ptBR));
        double margem = 0;
        double valor = 0;
        String strMargem, strValor;
        boolean ok = false;
        do {
            strMargem = JOptionPane.showInputDialog(null, "Entre com a margem em porcentagem (exemplo: 5,00 )");
            try {
                margem = df.parse(strMargem).doubleValue();
                ok = true;
            } catch (ParseException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog (null, "ERRO - Entre com um valor válido para a margem. Exemplo: 5,00");
            }
        } while (!ok);
        ok = false;
        do {
            strValor = JOptionPane.showInputDialog(null, "Entre com o valor em reais (exemplo: 1.000,00 )");
            try {
                valor = df.parse(strValor).doubleValue();
                ok = true;
            } catch (ParseException ex) {
                JOptionPane.showMessageDialog (null, "ERRO - Entre com um valor válido. Exemplo: 1.000,00");
            }
        } while (!ok);
        double valorCalculado = margem / 100.0 * valor;
        String resposta = String.format (ptBR, "Usando a margem de %.2f %% sobre o valor de %.2f, o resultado é %.2f", 
            margem, valor, valorCalculado);
        JOptionPane.showMessageDialog (null, resposta);
    }
}

Aqui tem uma complicaçãozinha por causa das vírgulas (não pontos decimais), mas fora isso, é tranquilo :slight_smile:

al.barbosa

entanglement:
É por isso que o pessoal reclama que Java é complicado.
Logo de cara apresentam o rapaz ao BigDecimal, que só deve ser usado em algumas situações :slight_smile:

No caso específico que ele queria, um double é suficiente, sabendo é claro formatar o número adequadamente (normalmente, um System.out.printf ou um String.format é mais que suficiente).

No livro Java Efetivo, de Joshua Bloch, é recomendado evitar float e double onde são requeridas respostas exatas.
É aconselhado também usar BigDecimal, int ou long para cálculos monetários.
Se o Danilo pretende utilizar o programa para obter respostas exatas, em particular se pretende fazer cálculos monetários, acho recomendável que ele utilize BigDecimal (ou int ou long).

Não acho tão complicado assim usar o BigDecimal, e não acho que o pessoal tenha razão de reclamar que Java é complicado por causa disso.

Coloco abaixo um código para mostrar o que pode acontecer ao realizar cálculos monetários com double:

A regra de negócio é a seguinte: uma empresa concede um empréstimo somente aos funcionários cujo salário liquido é menor ou igual a um valor limite. O salario líquido é o salario bruto menos o desconto. O codigo abaixo verifica se o empréstimo é valido usando ponto flutuante e big decimal.

No meu computador, com processador Intel e Windows 7, ao usar ponto flutuante o sistema nega o empréstimo a um funcionário que deveria ter direito.

import java.math.BigDecimal;

public class PontoFlutuante {
    public static void main(String[] args) {
        System.out.println("Calculo usando ponto flutuante:");
        pontoFlutuante();
        System.out.println();
        System.out.println("Calculo usando big decimal:");
        bigDecimal();
    }
    
    private static void pontoFlutuante(){
        double salario_bruto = 1000.70;
        double desconto = 500.30;
        double salario_liquido = salario_bruto - desconto;
        double limite = 500.40;
        
        System.out.println("Valor do salario liquido: " + salario_liquido);
        
        if(salario_liquido <= limite){
            System.out.println("Emprestimo valido");
        }else{
            System.out.println("Emprestimo invalido");
        }
    }
    
    private static void bigDecimal(){
        BigDecimal salario_bruto = new BigDecimal("1000.70");
        BigDecimal desconto = new BigDecimal("500.30");
        BigDecimal salario_liquido = salario_bruto.subtract(desconto);
        BigDecimal limite = new BigDecimal("500.40");
        
        System.out.println("Valor do salario liquido: " + salario_liquido);
        
        if(salario_liquido.compareTo(limite) <= 0){
            System.out.println("Emprestimo valido");
        }else{
            System.out.println("Emprestimo invalido");
        }
    }
}

Pode-se pensar que é uma situação muito difícil de acontecer, mas num sistema que realiza milhares de transações a probabilidade de ocorrer aumenta. O funcionamento inadequado em uma transação pode ser um problema bastante sério.

E

Concordo nesse ponto com você.

Tanto é que quem já fez contas com double uma vez na vida sabe que quando há comparações deve-se tomar cuidado, e sempre deixar uma certa tolerância.

A propósito, que raio de critério esquisito de empréstimo é esse (se seu salário líquido for MENOR ou IGUAL ao limite ele é concedido? ) Parece coisa de empréstimo a fundo-perdido.

O jeito correto de se fazer essa conta, mas que poucas pessoas sabem, é:

private static void pontoFlutuante(){  
        double salario_bruto = 1000.70;  
        double desconto = 500.30;  
        double salario_liquido = salario_bruto - desconto;  
        double limite = 500.40;  
          
        System.out.println("Valor do salario liquido: " + salario_liquido);  
          
        if(salario_liquido - limite < 0.01){  
            System.out.println("Emprestimo valido");  
        }else{  
            System.out.println("Emprestimo invalido");  
        }  
    }
al.barbosa

entanglement,

Esse critério é hipotético.
Concordo que dá para contornar o problema deixando uma tolerância ou arredondando os resultados.
Mas acho mais seguro usar um tipo que trabalhe com resultados exatos como BigDecimal, acho que o sistema fica mais robusto. Vai que um programador que não tome os cuidados com o ponto flutuante faça manutenção, há o risco dele introduzir bugs.

E

Também concordo. Até que vai que alguém audita esse código e descobre essas tolerâncias aí - parece aquela história de roubar centavos e pôr na conta 88888-8 :slight_smile:

(A conta 88888 foi usada pelo Nick Leeson - que afundou o banco Barings, aliás. Assistam ao filme “Rogue Trader”).

Criado 21 de junho de 2012
Ultima resposta 25 de jun. de 2012
Respostas 21
Participantes 6