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
-~----------~----~----~----~------~----~------~--~---
[flexdev] Re: O Flex não sabe somar!? Matemátic a Básica
Luis Eduardo - Suprasis Softwares Wed, 14 Nov 2007 09:06:27 -0800
- [flexdev] O Flex não sabe somar!? Matemá... Tião da Obra
- [flexdev] Re: O Flex não sabe somar... Beck Novaes
- [flexdev] RES: [flexdev] Re: O ... Henrique
- [flexdev] Re: RES: [flexdev... Mário Júnior
- [flexdev] Re: RES: [flexdev... Tião da Obra
- [flexdev] Re: O Flex não sabe somar... Beck Novaes
- [flexdev] Re: O Flex não sabe s... Luis Eduardo - Suprasis Softwares
- [flexdev] Re: O Flex não sa... Beck Novaes
- [flexdev] Re: O Flex nã... Mário Júnior
- [flexdev] Re: O Flex nã... Fabio Terracini
- [flexdev] Re: O Fl... Rodrigo Pereira Fraga
- [flexdev] Re: O Fl... Richard Manzke
- [flexdev] Re: O Flex nã... Tião da Obra
- [flexdev] Re: O Flex não sa... Tião da Obra
