Arredondar números

19 respostas
I

Olá,

Alguém sabe me informar como faço para arredondar números??

Exemplo: de 0,0099999 para 0,01

Obrigada

19 Respostas

odair.bonin

Olá irisvanda,

Experimente utilizar o método Math.ceil(). Verifique se este atende ao que vc precisa.

double resultado = Math.ceil(0,0099999);

Abraços

I

Oi,

O ceil arrendondou para 1.0, eu queria que arredonda-se para 0.01

quikkoo

as funções ceil e floor arredondam pra valores inteiros, nesse caso vc vai ter q multiplicar por 100, arredondar e dividir por 100 pra ser do jeito que vc quer, veja se isso resolve seu problema

double round(double numero, int precisao)
{
	double aux = 1.0;

	// Math.pow(10, precisao);
	// como a midp nao tem pow...
	for (int i = 0; i < precisao; i++
		aux *= 10.0

	numero *= aux;
	numero = Math.ceil(numero);
	numero /= aux;


	return numero;
}

flw, t+

gobbo

quikkoo, isso funciona mas num eh muito instavel nao?

pode-se usar classe NumberFormat para tal…

quikkoo

gobbo:
quikkoo, isso funciona mas num eh muito instavel nao?

pode-se usar classe NumberFormat para tal…


se vc escrever essa função pra j2me então pode né, mas no fim das contas essa classe da j2se vai acabar fazendo algo parecido com isso, então eu acho melhor resolver o problema ali mesmo

inté

gobbo

quikkoo:

se vc escrever essa função pra j2me então pode né, mas no fim das contas essa classe da j2se vai acabar fazendo algo parecido com isso, então eu acho melhor resolver o problema ali mesmo

inté

aaaah sim
eh j2me
entao esta certo
eh isso mesmo

hehe foi malz

I

Olá pessoal,

Este trecho me serviu em alguns casos, mas em outros não. Exemplo: serviu no caso 0,009999999 convertendo para 0.01; não serviu quando passei um 0.800000000000007, pois eu queria que convertesse para 0.80 e ele fez para 0.81.
O meu problema é que toda vez que faço uma operação com doubles eles nunca me retornam os valores reais, por exemplo: 140 - 139.99, o resultado deveria ser 0.01, mas o que me retorna é 0.0099999999999.

Estou utlizando a seguinte classe para manipular estes números, se alguém puder analisar e me ajudar a resolver o problema eu agradeço!!!

public class ValorDecimal
{

	private double d;
	private boolean bIsValid; 
	
	public ValorDecimal()
	{
		bIsValid = true;
	}

	public ValorDecimal( double d )
	{
		//recebe um double
                                bIsValid = true;
		double num = d*100;
		num = Math.ceil(num);
		num/=100;
		this.d = num;
	}

	public ValorDecimal( String s )
	{
                              //Recebe uma String		
                               bIsValid = true;
		try
		{
			this.d = Double.parseDouble(s);
		}
		catch ( Exception expt )
		{
			String sAux = new String(s);
			String r = new String("");
			for ( int a = 0; a < sAux.length(); a++ )
			{
				if ( "[telefone removido],".indexOf(sAux.substring(a,a+1)) > -1 )
				{
					if ( sAux.substring(a,a+1).compareTo(",") != 0 )
					{
						r += sAux.substring(a,a+1);
					}
					else
					{
						if ( r.indexOf(".") == -1 )
						{
							r += ".";
						}
					}
				}
			}
			try
			{
				double num = Double.parseDouble(r);
				num = Math.ceil(num);
				num/=100;
				this.d = num;
				//this.d = Double.parseDouble(r);
			}
			catch ( Exception expt2 )
			{
				bIsValid = false;
			}
		}
	}

	public ValorDecimal( String si, String sd )
	{
		//Recebe duas strings, uma com a parte inteira e outra a parte decimal
                                bIsValid = true;
		String sitrat = new String("");
		for ( int z = 0; z < si.length(); z++ )
		{
			if ( "-[telefone removido]".indexOf(si.substring(z, z + 1)) > -1 )
			{
				sitrat += si.substring(z, z + 1);
			}
		}
		try
		{
			int I = Integer.parseInt(sitrat);
			int D = Integer.parseInt(sd);
			I *= 100;
			I += D;
			d = new Integer(I).doubleValue();
			d /= 100;
		}
		catch ( Exception expt )
		{
			bIsValid = false;
		}
	}

	public String getI()
	{
		//retorna apenas a parte inteira
                               double n = d * 100;
		Double N = new Double(n);
		int i = N.intValue();
		String s = new Integer(i).toString();
		if ( s.length() > 2 )
		{
			return s.substring(0, s.length() - 2); 
		}
		else
		{
			return "0";
		}
	}

	public String getD()
	{
		//Retorna apenas a parte decimal
                                double n = d * 100;
		Double N = new Double(n);
		int i = N.intValue();
		String s = new Integer(i).toString();
		if ( s.length() > 2 )
		{
			return s.substring(s.length() - 2, s.length()); 
		}
		else if ( s.length() == 1)
		{
			return "0"+s;
		}
		else
		{
			return s;
		}
	}

	public double getValor()
	{
		//retorna um double formatado
                                double num = d*100;
		num = Math.ceil(num);
		num/=100;
		return d;
	}
	
	public String formatedValue()
	{
		//Retornar o valor em forma de String formada com o R$

                                String sI = this.getI();
		String sD = this.getD();
		
		String sSimMon = new String("R$");
		String sSimSepDec = new String(",");
		
		try
		{
			ConfiguracaoEN oConfiguracao = new ConfiguracaoDAO().obterObjeto();
			if ( oConfiguracao != null )
			{
				sSimMon = oConfiguracao.getMoeda();
				sSimSepDec = oConfiguracao.getSeparadorDecimal();
			}
		}
		catch ( Exception expt )
		{
			// nada a fazer
		}

		return sSimMon + " " + sI + sSimSepDec + ( sD.length() == 1 ? "0" : "" ) + sD;
	}
	
	public boolean isValid()
	{
		return bIsValid;
	}
}
T

Isso é coisa da aritmética de ponto flutuante, agravada pelo fato que o Java, em vez de imprimir apenas 6 casas depois da vírgula (como faz o C e o VB), imprime todas que pode imprimir. Se você usar java.text.DecimalFormat e limitar o número de casas impressas, ou então fazer as contas com java.math.BigDecimal*, então o problema não aparece.

  • Alerta - java.math.BigDecimal é notoriamente chata de usar. Só use se estritamente necessário.
I

Estão disponíveis em JME? Pq muita coisa que funciona em java não serve em JME.

T

EDIT - Desconsidere o que postei abaixo, porque não vi que era JavaME.

Dica: este método (public String formatedValue()) pode ser muito simplificado se você souber usar corretamente DecimalFormat.
DecimalFormat é bem mais rápido e correto.

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


public class ExemploMoeda {
	public static void main(String[] args) {
		double moeda = 12345.67;
		// Fazendo as coisas "no braço"
		NumberFormat nf = new DecimalFormat ("R$ #,##0.00", new DecimalFormatSymbols (new Locale ("pt", "BR")));
		System.out.println (nf.format(moeda));
		// Você também pode usar o formato enlatado do Java, assim:
		nf = DecimalFormat.getCurrencyInstance(new Locale ("pt", "BR"));
		System.out.println (nf.format(moeda));
		// getCurrencyInstance conhece as moedas de vários países. Veja um exemplo:
		nf = DecimalFormat.getCurrencyInstance(new Locale ("es", "AR"));
		System.out.println (nf.format(moeda)); // Argentina - $12.345,67
		nf = DecimalFormat.getCurrencyInstance(new Locale ("es", "ES"));
		System.out.println (nf.format(moeda)); // Espanha - 12.345,67 ?
		nf = DecimalFormat.getCurrencyInstance(new Locale ("en", "GB"));
		System.out.println (nf.format(moeda)); // Inglaterra - £12,345.67
		nf = DecimalFormat.getCurrencyInstance(new Locale ("jp", "JP"));
		System.out.println (nf.format(moeda)); // Japão - JPY 12,346
		nf = DecimalFormat.getCurrencyInstance(new Locale ("cn", "CN"));
		System.out.println (nf.format(moeda)); // China - CNY 12,345.67
	}
}

O código que você fez infelizmente é grande demais; use DecimalFormat e seja feliz!

I

Tentei importar o que vc citou no exemplo, mas não encontro este pacote java.text no JME. Estou utilizando Eclipse, preciso baixar algum plugin adicional?

T

Pois é, como é JavaME, é necessário usar uma solução mais parecida com a sua. Deixe-me ver mais ou menos como seria; só me dê uns instantes.

I

Tudo bem, eu agradeço!

Fico no aguardo

T
public class ExemploMoedaJavaME {

	// Formatação sem separação de milhares. Exemplo: R$ 12345,67
	public static String formatarMoeda (double d) {
		if (d >= 0)
		return "R$ " + 
			(long) d + 
			"," + 
			("" + (long) (0.5 + 100.0 + 100.0 * (d - Math.floor(d)))).substring(1); 
		// Note o 0.5 usado aqui para fazer arredondamento.
		else {
			return "(" + formatarMoeda (-d) + ")";
		}
	}
	
	public static void main(String[] args) {
		double[] moedas = {
			0.0,
			12.00,
			1.2345,
			1234.56,
			1234.01,
			1234.00,
			12.34,
			12.00,
			123457678.99,
			123348.81,
			-2345.45
		};
		for (int i = 0; i < moedas.length; ++i) {
		System.out.println (formatarMoeda(moedas[i]));
		}
	}
}

Se você tiver de separar em milhares aí é um pouco mais complicado, mas acho que você deve ter entendido como é meio chato fazer contas.

quikkoo

use floor ao invés de ceil… floor arredonda pra baixo enquanto ceil arredonda pra cima, tb não pra querer q o programa adivinhe tudo que vc quer

mas se vc usa pontos flutuantes apenas pra cáuculo de moeda (dinehiro) onde existirá sempre duas casas decimais, então a dica que eu t dou é usar sempre inteiros, por alguns motivos, um deles é esse perrengue que vc tá passando pra arredondar os valores, outro motivo é q cálculos com pontos flutuantes são mais lentos doq cálculos com inteiros e isso é um peso pra “micro máquina virtual” do aparelho

depois quando for exibir os valores vc acrescenta uma máscara que coloca a virgula depois da segunda casa e um ponto a cada tres casas, sem dúvida isso é mais simples de se implementar e vai reduzir a carga da sua aplicação

flw, t+

I

Valeu…
Vou tentar fazer diferente!

Obgda pela força

Miguel_Frazao

Olá Quikkoo,

De fato encontrei uma dica como a sua (http://developers.sun.com/mobility/midp/questions/float), mas não sei como acrescentar a máscara no J2ME. De qualquer Irisvanda você pode tentar usar bibliotecas de terceiros tais como MicroFloat (http://www.dclausen.net/) ou o MathFP (http://home.comcast.net/~ohommes/jScience/download.html).

Estou com o mesmo problema. Ao tentar fazer uma conta de multiplicação simples:
double subTotal = (qtd * preco); // 2.45 * 9.9
obtenho o resutado: 24.255000000000003

Estou dando uma olhada na documentação que acompanha as bibliotecas.

I

Olá Miguel,
Acredito que para utilizar ineiros vc teria que converter o resultado para String e adicionar uma vígula antes da penultima substring
Ainda não tentei, mas acredito que vai ajudar

Abraços

Miguel_Frazao

Olá Irisvanda,

Perdoe a incipiência dos meus conhecimentos, mas quanto a esta solução (adicionar uma vígula antes da penultima substring), essa tem sido justamente a dificuldade. Agradeceria imensamente se alguém tivesse algum código de susgestão. Até aqui minhas tentativas, estudando a documentação e pesquisando nos forums, ainda não tiveram sucesso.

Criado 13 de maio de 2008
Ultima resposta 21 de mai. de 2008
Respostas 19
Participantes 6