DevMedia - asp.net, Java, Delphi, SQL e web Design, tudo em um só lugar!
Bem vindo a DevMedia!
LOGIN:     SENHA:
 
 

  Este é um post disponível para assinantes MVP
Este post também está disponível para assinantes da Java Magazine DIGITAL ou para quem possui Créditos DevMedia.  Clique aqui para saber mais!


Artigo Java Magazine 19 - Byte Code

Artigo publicado pela Java Magazine 19.

Esse artigo faz parte da revista Java Magazine edição 19. Clique aqui para ler todos os artigos desta edição

jm19_capa.gif 

Byte Code

Matemática em Java

Mastigando Números na JVM

Entenda e explore os recursos de matemática da J2SE, tanto em ponto flutuante como números decimais

Quando se trata de Matemática, seria ótimo que o computador fizesse o que aprendemos na escola. Temos consciência de algumas diferenças, como a precisão limitada de tipos numéricos como int ou mesmo double, mas a realidade é um pouco mais complicada. Existem vários fatos que precisamos conhecer bem para evitar problemas e para executar cálculos com precisão e desempenho.

Java não é uma linguagem criada especialmente para a programação numérica (como Fortran). Os tipos de dados e APIs disponíveis na J2SE são mais que suficientes para a maioria das aplicações, mas não atendem às necessidades de muitos nichos, como aplicações de engenharia, científicas, gráficos avançados, e outras que precisem de cálculos mais complexos. Por exemplo, Java não tem suporte nativo a números complexos, matrizes ou vetores da álgebra linear, e não inclui APIs para resolver equações lineares, fazer interpolações, análises estatísticas etc. Há bibliotecas de terceiros que oferecem esses recursos para quem precisar (para um exemplo, veja o quadro “Commons Math etc.”). Porém, como veremos, tudo aquilo que o Java implementa, faz direito – ao contrário da grande maioria das linguagens. Numa outra vertente, também podemos precisar de matemática decimal exata, mais adequada para tarefas como cálculos financeiros. Isso é suportado pelas APIs de aritmética decimal, que também examinaremos.

Quando lemos os JavaDocs das APIs numéricas (como java.lang.Math e java.math.BigDecimal), nos deparamos com conceitos obscuros como ULPs, semi-monotonicidade, norma IEEE, meta-números (como NaN), precisão versus escala, regras de arredondamento... Pode parecer que tais detalhes só interessam (e só podem ser compreendidos) por matemáticos profissionais mas, na prática, um conhecimento mais profundo da matemática computacional revela-se acessível e bastante útil.

Neste artigo, vamos explicar esses conceitos e ilustrá-los com exemplos práticos, que mostram o impacto de diferentes técnicas de programação numérica. Além disso, em muitas aplicações, o desempenho dos cálculos costuma ser tão importante quanto sua precisão, mas os benchmarks mais populares costumam focar somente no desempenho. Aqui, tentei abordar essa questão de forma integrada, com um novo benchmark gráfico que explora tanto a velocidade quanto a qualidade dos cálculos, o que também serve para ilustrar noções que parecem um tanto abstratas.

FP em Java

Os tipos float e double do Java seguem o padrão IEEE-754 com grande rigor (veja o quadro “O padrão IEEE-754 e Java”, onde também são definidos alguns termos importantes usados neste artigo). A maioria das linguagens evita alguns casos suportados pelo Java em troca de algum desempenho. Todavia, estes custos têm-se tornado menores com o avanço dos compiladores e também das CPUs, cujas unidades de ponto flutuante (FPUs) são cada vez mais poderosas.

Um fator sempre importante no Java é a portabilidade. Cálculos de ponto flutuante não são exatos, precisando, na maioria das vezes, serem aproximados, e pode haver diferentes algoritmos para computar alguma função não suportada diretamente pela CPU. Os algoritmos mais precisos costumam ser mais lentos – em linguagens tradicionais como C/C++, cada compilador faz uma opção diferente. No Java, todavia, o padrão exige que todos os cálculos de ponto flutuante sejam reproduzíveis bit por bit em qualquer implementação da JVM, para qualquer plataforma.

Reprodutibilidade bit-por-bit

Reprodutibilidade bit por bit significa que, para qualquer operação x = f(a1,a2,...,aN), se a representação binária dos argumentos (a1..aN) for exatamente igual, bit por bit, o resultado deve ser o mesmo em qualquer plataforma, também bit por bit. Para um valor double, por exemplo, o valor em bits é obtido com Double.doubleToLongBits(valor). Mas por que essa especificação?

Primeiro, em cada plataforma, o padrão de bits correspondente a este valor poderia ser diferente. Isso poderia acontecer porque uma das plataformas não utiliza a representação IEEE-754. Ou porque utiliza uma precisão maior que a necessária (como 80 bits, nos chips Intel). Ou então, poderiam usar algoritmos diferentes para calcular funções de biblioteca, gerando resultados ligeiramente diferentes devido a diferenças de precisão ou arredondamento.

Mas em Java nenhuma discrepância é permitida: nem sequer num único bit. Digamos que um mesmo cálculo seja feito em duas JVMs diferentes, produzindo os resultados x’ e x’’, que deveriam ser iguais, mas diferem apenas no último bit da mantissa (um erro minúsculo de precisão). Se esses valores fossem usados num cálculo como yx, aquele erro pequenino logo se tornaria bem maior. Ou então, digamos que o valor produzido numa das plataformas seja transmitido para a outra e ambos são comparados: x1 == x2 resultaria em false, novamente devido àquela diferença mínima no último bit.

Aderência à norma IEEE

Além dos tipos e operações básicas, a norma IEEE-754 também determina (às vezes de forma opcional) comportamentos desejáveis para algumas funções matemáticas. A plataforma Java especifica todas as funções matemáticas de forma compatível com a norma, mesmo quando a norma IEEE é opcional. Isso não é comum em outras linguagens. Você sabe, por exemplo, como o Java implementa a função "



ATENÇÃO! A exibição deste artigo foi interrompida.


  Este é um post disponível para assinantes MVP
Este post também está disponível para assinantes da Java Magazine DIGITAL ou para quem possui Créditos DevMedia.  Clique aqui para saber mais!






    0 COMENTÁRIO

[Fechar]

Este post é fechado - você precisa ter acesso ao post para incluir um comentário.


Nenhum comentário foi postado - seja o primeiro a comentar!



Publicidade
Autor
Osvaldo Pinali Doederlein

é Mestre em Engenharia de Software Orientado a Objetos e Arquiteto de Tecnologia da Visionnaire Informática, trabalhando em projetos de software e prospecção tecnológica.


Space do autor
Estatísticas
Favorito:
Comentários:
Feedback:
Utilidade:
0   0
[Fechar]

Você precisa estar logado para dar um feedback.

Clique aqui para efetuar o login
[Fechar]


Este post está fechado. Saiba mais sobre a assinatura MVP!
web-03
DevMedia  |  Anuncie  |  Fale conosco
Hospedagem web por Porta 80 Web Hosting
2012 - Todos os Direitos Reservados a web-03