ole1990 Posted February 25, 2012 at 01:36 AM Report Share #441095 Posted February 25, 2012 at 01:36 AM Bom dia, Ao fazer divisão com varias casa decimais ele mete-me resultados incorrectos. Ou seja exemplo 125.458/10=12.545799996546 quando não são outros resultados, como posso fazer para corrigir esse erro? Link to comment Share on other sites More sharing options...
pedrotuga Posted February 25, 2012 at 02:03 AM Report Share #441096 Posted February 25, 2012 at 02:03 AM Os computadores são máquina de precisão finita. Se perceberes a essência dos números reais, perceberás que entre dois valores existe uma infinidade de valores. É naturalmente impossível para um computador poder ter um sistema numérico que cubra um número infinito de valores. No caso de um float, é umpossível representar o valor 12.5458. O mais próximo que é possível é esse valor que afixaste. Se reparares, o erro é dez mil vezes menor que a grandeza representada peloo algarismo menos significativo do teu dividendo. Pelo que eu diria que, se estiveres a fazer calculos numéricos aproximados, este erro não te faz diferença absolutamente nenhuma. Talvez o que querias é formatar a apresentação do número de forma a que fique mais 'bonito'. Vê estes links http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html http://www.exampledepot.com/egs/java.text/FormatNum.html Link to comment Share on other sites More sharing options...
ole1990 Posted February 25, 2012 at 02:20 AM Author Report Share #441097 Posted February 25, 2012 at 02:20 AM Obrigado pela resposta, Sou estudante em engenharia informática penso que irei dar isso em breve na faculdade. Sim era realmente o que eu queria, porque para uma calculador (é o que estou a fazer) não faria sentido nenhum haver um numero desse tamanho. Link to comment Share on other sites More sharing options...
bsccara Posted February 25, 2012 at 02:25 AM Report Share #441098 Posted February 25, 2012 at 02:25 AM Se precisas de cálculos exactos com uma precisão definida, existem bibliotecas de cálculo em virgula fixa. Os cálculos são feitos com um determinado número de digitos de precisão e são garantidamente exactos. Mas como a maneira como o FPU faz os cálculos não é exacta, essas bibliotecas fazem os cálculos usando o ALU, pelo que são muito mais lentas. Mas para exactidão são a única solução. Vê: http://en.wikipedia.org/wiki/Fixed-point_arithmetic P.S. Obviamente mesmo assim existem limites à precisão (o número 1.245 não é representável em virgula fixa com 2 digitos decimais) mas são controlados pelo utilizador da bibilioteca. Link to comment Share on other sites More sharing options...
pedrotuga Posted February 25, 2012 at 03:26 AM Report Share #441102 Posted February 25, 2012 at 03:26 AM Se precisas de cálculos exactos com uma precisão definida, existem bibliotecas de cálculo em virgula fixa. Os cálculos são feitos com um determinado número de digitos de precisão e são garantidamente exactos. Mas como a maneira como o FPU faz os cálculos não é exacta, essas bibliotecas fazem os cálculos usando o ALU, pelo que são muito mais lentas. Mas para exactidão são a única solução. Vê: http://en.wikipedia.org/wiki/Fixed-point_arithmetic P.S. Obviamente mesmo assim existem limites à precisão (o número 1.245 não é representável em virgula fixa com 2 digitos decimais) mas são controlados pelo utilizador da bibilioteca. Para esclarecer quem eventualmente leia isto, a tua resposta tem algumas incorrecções. Calculos exactos não têm uma 'precisão definida'. Calculos exactos não têm precisão, são exactos. Ser exacto é precisamente o contrário de ter uma determinada precisão. Tipos de dados numéricos de virgula fixa, permitem ter a mesma precisão ao longo da sua extensão toda, ao contrario de tipos de dados com vírgula flutuante que têm mais precisão em torno de um determinado valor (tipicamente zero) e menos precisão conforme nos aproximamos do limite da escala. Mas mais importante que vírgula flutuante é a base do sistema numérico. Os tipos de dados mais frequentes têm base binária por motivos praticos. Uma vez que 1/10 é uma dizima infinita em binário, é impossível representar exactamente 0.1 com um tipo de dados que tenha base binária, seja ele de vírgula flutuante ou de vírgula fixa. Um tipo de dados decimal resolve este problema, mas é extremamente ineficiente em termos computacionais e a sua implementação exige muito mais recursos. Para calculos exactos, é preciso usar uma biblioteca de calculo simbólico/algébrico. Essas bibliotecas contêm milhares de algoritmos para fazer simplificações matemáticas semelhantes às que nós humanos fazemos com papel e caneta. Mas isto estamos a entrar numa área de computação completamente diferente. Outra tecnologia relevante são os tipos de dados de precisão arbritrária. Estes tipos de dado usam quanta precisão for precisa dentro dos limites. Se se usar um tipo de dados destes para calcular por exemplo 1/3, ele vai calcular 1.33333333333333333... por aí fora até encher a memória do computador com '3'. Link to comment Share on other sites More sharing options...
pmg Posted February 25, 2012 at 10:34 AM Report Share #441118 Posted February 25, 2012 at 10:34 AM Uma palavra ... ou melhor: um link :-) What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código! Link to comment Share on other sites More sharing options...
veaoum Posted February 25, 2012 at 04:31 PM Report Share #441134 Posted February 25, 2012 at 04:31 PM Uma pergunta estupida. Se em vez de dividires 125.458/10 Dividires: 125458/10000 Ainda dá erro? Link to comment Share on other sites More sharing options...
pedrotuga Posted February 25, 2012 at 05:09 PM Report Share #441135 Posted February 25, 2012 at 05:09 PM Uma pergunta estupida. Se em vez de dividires 125.458/10 Dividires: 125458/10000 Ainda dá erro? Dá, o problema não é com o algoritmo de da divisão. O problema é que não consegues escrever 12.5458 em binário. Em boa verdade nem mesmo 125.458, o computador guarda o valor mais proximo que encontrar. Link to comment Share on other sites More sharing options...
mjamado Posted February 25, 2012 at 05:39 PM Report Share #441136 Posted February 25, 2012 at 05:39 PM O problema está longe de ser algorítmico, e a implementação do Java não é caso único. A maioria das implementações Javascript dos browsers sofre do mesmo mal, e o Actionscript, então, tem problemas ainda mais graves, devido ao tamanho reduzido do tipo Number. "Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web. Link to comment Share on other sites More sharing options...
veaoum Posted February 25, 2012 at 05:46 PM Report Share #441138 Posted February 25, 2012 at 05:46 PM Hum... Ok a minha ideia era trabalhar com inteiros até ter o resultado e só depois aplicar-lhe a virgula. Qualquer inteiro é possível representar atravez de binarios, o problema esta na virgula certo? assim o computador apenas trata da virgula no fim, quando já não tem que efectuar cálculos. Link to comment Share on other sites More sharing options...
pedrotuga Posted February 26, 2012 at 11:32 AM Report Share #441187 Posted February 26, 2012 at 11:32 AM Hum... Ok a minha ideia era trabalhar com inteiros até ter o resultado e só depois aplicar-lhe a virgula. Qualquer inteiro é possível representar atravez de binarios, o problema esta na virgula certo? assim o computador apenas trata da virgula no fim, quando já não tem que efectuar cálculos. Qualquer não, mas o int é contínuo sim. Não tem saltos, cobre os inteiros todos dentro dos seus limites. Podes fazer isso que disseste, mas tens a certeza que calculos exactos é o que queres fazer e que não ficarias melhor servido simplesmente formatando os números a teu belo prazer? No teu caso o erro é 10000 vezes mais pequeno que o teu ultimo algoritmo significativo. Caso precises de calculos exactos, deves estar ciente que te basta uma divisão por três para te estragar o esquema. Link to comment Share on other sites More sharing options...
bsccara Posted February 26, 2012 at 06:49 PM Report Share #441232 Posted February 26, 2012 at 06:49 PM Calculos exactos não têm uma 'precisão definida'. Calculos exactos não têm precisão, são exactos. Ser exacto é precisamente o contrário de ter uma determinada precisão. Falando em termos puramente matemáticos, tens razão. Mas em computação trabalhamos sempre em função duma precisão definida, seja o nº de digitos significativos num float ou o nº de bits num int. Mas ainda assim acho possível determinar se o cálculo é ou não exacto, dentro do constragimento imposto pela precisão definida. É nesse contexto que penso. Tipos de dados numéricos de virgula fixa, permitem ter a mesma precisão ao longo da sua extensão toda, ao contrario de tipos de dados com vírgula flutuante que têm mais precisão em torno de um determinado valor (tipicamente zero) e menos precisão conforme nos aproximamos do limite da escala Não é o meu entendimento, precisamente por causa da virgula ser flutuante. Indica um link exemplificativo, por favor. Pelo que eu diria que, se estiveres a fazer calculos numéricos aproximados, este erro não te faz diferença absolutamente nenhuma. Atenção com esse raciocínio. É extremamente frequente fazer uma sequência de operações matemáticas e depois ter de comparar o resultado com zero, para efeitos algorítmicos. Esses pequenos erros de representação podem significar que a comparação nunca dará um resultado de verdadeiro. Dá, o problema não é com o algoritmo de da divisão. O problema é que não consegues escrever 12.5458 em binário. Em boa verdade nem mesmo 125.458, o computador guarda o valor mais proximo que encontrar. Não exactamente. O BCD é binário mas consegue representar esse número exactamente. Mas em virgula flutuante numeração de base 2, sim tens razão. Link to comment Share on other sites More sharing options...
pedrosorio Posted February 26, 2012 at 08:06 PM Report Share #441242 Posted February 26, 2012 at 08:06 PM Falando em termos puramente matemáticos, tens razão. Mas em computação trabalhamos sempre em função duma precisão definida, seja o nº de digitos significativos num float ou o nº de bits num int. Mas ainda assim acho possível determinar se o cálculo é ou não exacto, dentro do constragimento imposto pela precisão definida. É nesse contexto que penso. Pensas mal. Não é o meu entendimento, precisamente por causa da virgula ser flutuante. Indica um link exemplificativo, por favor. http://en.wikipedia.org/wiki/Single_precision_floating-point_format O formato padrão de floating point. Dado que o expoente tem 8 bits e um bias de 127 (i.e. no cálculo subtraímos 127 ao valor representado no expoente), é possível representar expoentes entre -127 e 128. Os 23 bits da fracção representam um número no intervalo [1,2[ (mais precisamente [1, 2-2^(-23)]). Como tal é fácil ver que todos os números que tenham os 8 bits do expoente inferiores ou iguais a 127 (i.e. expoente do número inferior ou igual a 0), e que são metade dos números que podem ser representados por um floating point, estão contidos no intervalo ]-2, 2[. Um floating point consegue representar 2^(32) números no intervalo dos reais (zero com sinal, infinitos, NaN, ok ok mas irrelevante para a ordem de grandeza). Metade destes, 2^31, estão no intervalo ]-2,2[. Parece-me significativamente mais precisão em torno de 0 do que no resto dos reais. Com vírgula fixa a precisão é igual em toda a extensão, porque é usado um bit para representar cada algarismo (binário). Não respondo a dúvidas por mensagem. Link to comment Share on other sites More sharing options...
bsccara Posted February 26, 2012 at 10:28 PM Report Share #441258 Posted February 26, 2012 at 10:28 PM Pensas mal. Não estamos a pensar na mesma coisa... http://en.wikipedia.org/wiki/Single_precision_floating-point_formatO formato padrão de floating point. Dado que o expoente tem 8 bits e um bias de 127 (i.e. no cálculo subtraímos 127 ao valor representado no expoente), é possível representar expoentes entre -127 e 128. Os 23 bits da fracção representam um número no intervalo [1,2[ (mais precisamente [1, 2-2^(-23)]). Como tal é fácil ver que todos os números que tenham os 8 bits do expoente inferiores ou iguais a 127 (i.e. expoente do número inferior ou igual a 0), e que são metade dos números que podem ser representados por um floating point, estão contidos no intervalo ]-2, 2[. Um floating point consegue representar 2^(32) números no intervalo dos reais (zero com sinal, infinitos, NaN, ok ok mas irrelevante para a ordem de grandeza). Metade destes, 2^31, estão no intervalo ]-2,2[. Parece-me significativamente mais precisão em torno de 0 do que no resto dos reais. Com vírgula fixa a precisão é igual em toda a extensão, porque é usado um bit para representar cada algarismo (binário). Obrigado pelo esclarecimento. Link to comment Share on other sites More sharing options...
pedrotuga Posted March 2, 2012 at 11:03 PM Report Share #442003 Posted March 2, 2012 at 11:03 PM Não foi minha intenção deixar o trabalho árduo de documentação para o pedrosório. De qualquer das formas, obrigado. Atenção com esse raciocínio. É extremamente frequente fazer uma sequência de operações matemáticas e depois ter de comparar o resultado com zero, para efeitos algorítmicos. Esses pequenos erros de representação podem significar que a comparação nunca dará um resultado de verdadeiro. Precisamente. Foi especificamente a isso que me referi. Um algoritmo que recorre a calculos exactos não deve usar tipos de dados numéricos porque estes são aproximados. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now