Este ultimo exemplo sugere que o problema pode mesmo existir (embora não tenha ocorrido com os exemplos de código do Daniel).
Pesquisando um pouco a respeito encontrei isso aqui: http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_13989&sliceId=1 O mais interessante (se é que podemos chamar isso de interessante) é o que está escrito na seção "Solution": "This is a fact of life in applications that use floating point arithmetic." Agora, conforme o próprio Luis Eduardo falou e também como pode ser visto neste Key Note da URL acima este não é um problema exclusivo do Flex. Portanto, não sei se é válido concluir a tecnologia é "... mais uma linguagem de programador iniciante... ". A solução mais elegante, talvez, seja mesmo criar o seu próprio BigDecimal. De fato, é isso que a maioria das linguagens fazem. A diferença no caso do Flex é que isso, a princípio, não faz parte do SDK. []'s Beck Novaes On 14 nov, 16:07, Luis Eduardo - Suprasis Softwares <[EMAIL PROTECTED]> wrote: > Compartilho da dor do Daniel. > Aqui aconteceu o mesmo problema uns tempos atrás. A solução que > adotei foi evitar, sempre que possível, realizar cálculos no lado do > Flex. Sempre que possível uso o back-end para calcular. > Quando não tem jeito mesmo e precisa efetuar o cálculo no lado do > Flex, uso o Number().toFixed(2) também. > > Pra conseguir ilustrar (e garantir de que realmente são os nossos > FBs que estão com erros) fiz um código pequeno aqui pra ser rodado em > modo Debug e todos poderem testar. Basta apertar o botão de calcular e > ver os dados gerados no trace (ou nos labels). Se sempre der ok para os > senhores, vocês sempre verão o número de resultado: 0.1 Caso o erro de > arredondamento aconteça, aparecerá o número 0.099999987 (ou algo assim) > > Só um comentário pessoal. Eu particularmente não acho isso um > problema tão grave uma vez que em qualquer linguagem, sem exceção, isso > sempre acontece para as operações de divisão. > O que me aborrece um pouco é o fato de ter que se preocupar também > com as operações de subtração e soma. Isso inclusive me parece meio sem > razão de ser, pelo que me recordo das aulas de ciência de computação de > 9 anos atrás (início da facul) e de como são somados os bits... enfim... > > abraços, > Luís Eduardo. > > código: > ----------------------------------------------------------------------------- > <?xml version="1.0" encoding="utf-8"?> > <mx:Application > xmlns:mx="http://www.adobe.com/2006/mxml" > width="100%" height="100%"> > > <mx:Form> > <mx:FormHeading label="Calculo de delta (Final - Inicial)"/> > <mx:FormItem label="Numero Inicial"> > <mx:TextInput id="edt1" text="1.1"/> > </mx:FormItem> > <mx:FormItem label="Numero Final"> > <mx:TextInput id="edt2" text="1.2"/> > </mx:FormItem> > </mx:Form> > > <mx:Button label="calcular" click="calcular()"/> > > <mx:Label id="lblValorReal" text="valor real calculado aqui"/> > <mx:Label id="lblValorTeorico" text="valor com aproximação aqui"/> > > <mx:Script> > <![CDATA[ > > public function calcular():void { > var num1:Number = Number(edt1.text); > var num2:Number = Number(edt2.text); > > trace("num1: "+num1); > trace("num2: "+num2); > > lblValorReal.text = (num2 - num1).toString(); > lblValorTeorico.text = (num2 - num1).toFixed(2); > > trace("(num2 - num1): "+(num2 - num1)); > if ( (num2 - num1) == 0.1) { > trace("igual a 0.1"); > } > else { > trace("valor diferente do esperado", "erro"); > } > > trace("solução feia, mas funcional:") > trace("(num2 - num1): "+Number(num2 - num1).toFixed(2)); > > trace("como para comparar numeros em vez de strings, é > preciso outro casting"); > if ( Number(Number(num2 - num1).toFixed(2)) == 0.1) { > trace("igual a 0.1"); > } > else { > trace("valor diferente do esperado", "erro"); > } > } > > ]]> > </mx:Script> > </mx:Application> > > ----------------------------------------------------------------------------- > > Beck Novaes escreveu: > > > Por favor, Daniel, confirme para nós a existência do problema porque > > isso é no mínimo intrigante. Acho que o seu post merece bastante > > atenção, pois eu nunca vi ninguém na lista criticar o Flex com tanta > > veemência. Você deve ter bons motivos para isso e a sua contribuição > > pode ser esclarecedora para a comunidade. > > > []'s > > Beck Novaes > > > On 14 nov, 08:58, Tião da Obra <[EMAIL PROTECTED]> wrote: > > >> Bom Dia Pessoal, > > >> Tenho aqui um problema clássico de soma e subtração, tanto pro JAVA, quanto > >> pro Flex. Já vi casos até no Ruby. Vamos ao exemplo: > > >> var x:Number = 10.03; > >> var y:Number = 0.07; > >> var z:Number = 9.9; > > >> var total:Number = 0; > >> total += x; //10.03 > >> total += y; //11.0000001 > >> total += z; //20.0000005 > > >> trace(total); // Total: [20.0000005] De onde surgiu o 0.0000005? > > >> Este problema acontece com menor freqüência nas somas, ou seja, quando a > >> operação é de Adição [ + ], agora vejamos o que acontece na subtração: > >> var x:Number = 20; > >> var y:Number = 10.07; > >> var z:Number = 9.93; > > >> var total:Number = 0; > >> total = x; //total = 20 > >> total -= y; //total = 9.93000001 De onde surgiu esse 0.00000001? O > >> correto seria 9.96 > >> total -= z; //total = -4.1000005 Esse é o resultado mais absurdo > >> de > >> todos os tempos. O correto seria zero. > > >> Em JAVA resolvemos esta questão fácil fácil com a classe BigDecimal. Mas, e > >> no Flex? Será que eu terei que criar uma classe BigDecimal só pra poder > >> realizar contas de somar? Que furada. > > >> Pior ainda é quando você precisa fazer comparações, exemplo: > >> Tenho o seguinte objeto: > > >> Parcela { > >> public var filial:String; > >> public var porcentagem:Number; > > >> } > > >> Tenho uma ArrayCollection cheio de objetos do tipo Parcela. Neste exemplo > >> nós temos uma Despesa que será dividida em várias parcelas, cada uma > >> contendo uma porcentagem. No final teremos que verificar se a soma de todas > >> as parcelas é igual a 100%. > > >> var lista:ArrayCollection = new ArrayCollection(); > > >> var parcelaX:Parcela = new Parcela(); > >> parcelaX.filial = "Filial X"; > >> parcelaX.porcentagem = 20.93; > >> lista.addItem(parcelaX); > > >> var parcelaY:Parcela = new Parcela(); > >> parcelaY.filial = "Filial Y"; > >> parcelaY.porcentagem = 49.07; > >> lista.addItem(parcelaY); > > >> var parcelaZ:Parcela = new Parcela(); > >> parcelaZ.filial = "Filial Z"; > >> parcelaZ.porcentagem = 30; > > >> var total:Number = 0; > >> for each ( var parcela:Parcela in lista ) { > >> total = total + parcela.porcentagem; > > >> //Tanto faz o tipo de soma é por incrementação ou não > >> //total += parcela.porcentagem > > >> } > > >> trace(total); //Total: 100.000000049 (De onde surgiu esse infeliz > >> desse 000000049?) > > >> if ( total == 100 ) { > >> trace("Parabéns, seu Flex aprendeu a somar");} else { > > >> Alert.show("Somatório Tabajara", "Erro"); > > >> } > > >> ============================================================================================================ > >> Resumo da história, como não sabemos resolver esse tipo de problema o jeito > >> é ir se virando com soluções falhas como o caso do arredondamento em que eu > >> converto pra String através do toFixed() e depois realizo um cast pra > >> Number > >> novamente. Agora imagine você ter que procurar em todos os trechos do > >> programa códigos de soma pra fazer essa conversão, é um tiro no pé. > > >> Number(total.toFixed(2)); > > >> Quando decidimos utilizar o Flex como solução para nossa empresa, estávamos > >> pensando em algo que fosse profissional e confiável, uma linguagem de bases > >> sólidas e maduras, e não mais uma linguagem de programador iniciante, que > >> não se decidiu até hoje se usa JAVA, Ruby, PHP, entre outras. Nossos > >> códigos > >> possuei quase 50 milhões de linhas, já pensou o que é um problema de soma, > >> quando o programa se trata de uma Folha de Pagamentos ou até mesmo um > >> programa de Contabilidade ou Contas a Pagar. > > >> Quer receber uns centavos a menos na sua folha de pagamento? Então, por > >> favor nos ajudem a resolver esse problema. > > >> Grande Abraço, > >> -Daniel Negri --~--~---------~--~----~------------~-------~--~----~ Você recebeu esta mensagem porque está inscrito na lista "flexdev" Para enviar uma mensagem, envie um e-mail para [email protected] Para sair da lista, envie um email em branco para [EMAIL PROTECTED] Mais opções estão disponíveis em http://groups.google.com/group/flexdev -~----------~----~----~----~------~----~------~--~---
