Tenha um fórmula matemática que está executando de forma diferente na máquina no cliente sem que eu modifique o código.
Já testei em diversas máquinas com as mesmas configurações e não consigo reproduzir…
Ou seja, o resultado comum é 132,2586, porém no cliente é 131,9552.
Alguém tem uma idéia de como corrigir isso visto que o certo é 132,2586.
/** * Calcular o Valor Presente de um titulo utilizando TIR Formula aplicada: * VP = VT / ( (TAXA + 1) ^ (PRAZO / taxaMesAnoDia ( 1/21/252) ) * * @param value * @param tax * @param time * @return */publicstaticBigDecimalcalculateValorPresenteByTIR(BigDecimalfileValue,BigDecimaltax,Integertime,IntegertaxaMesAnoDia){if(fileValue==null||fileValue.doubleValue()<=0){thrownewIllegalArgumentException("The argument 'fileValue' must contain a value");}if(tax==null||tax.doubleValue()<=0){thrownewIllegalArgumentException("The argument 'tax' must contain a value");}doublecurrentTax=roundDoubleValue(tax.doubleValue(),2);doublecurrentTime=roundDoubleValue(time.doubleValue(),2);doublecurrentFileValue=roundDoubleValue(fileValue.doubleValue(),2);doublep=(currentTime/taxaMesAnoDia);doublet=((currentTax/100)+1);returnnewBigDecimal(roundDoubleValue((currentFileValue/(Math.pow(t,p))),2));}
ViniGodoy
Não adianta nada você declarar seu tipo como BigDecimal, se as contas você está fazendo com double.
Dê uma lida aqui:
Você acha que utilizando esse código vai adiantar algo:
/** * Calcular o Valor Presente de um titulo utilizando TIR Formula aplicada: * VP = VT / ( (TAXA + 1) ^ (PRAZO / taxaMesAnoDia ( 1/21/252) ) * * @param value * @param tax * @param time * @return */publicstaticBigDecimalcalculateValorPresenteByTIR(BigDecimalcurrentFileValue,BigDecimalcurrentTax,Integertime,IntegertaxaMesAnoDia){if(currentFileValue==null||currentFileValue.doubleValue()<=0){thrownewIllegalArgumentException("The argument 'fileValue' must contain a value");}if(currentTax==null||currentTax.doubleValue()<=0){thrownewIllegalArgumentException("The argument 'tax' must contain a value");}BigDecimalcurrentTime=newBigDecimal(time.doubleValue());BigDecimalp=currentTime.divide(newBigDecimal(taxaMesAnoDia),2,RoundingMode.HALF_EVEN);BigDecimalt=currentTax.divide(newBigDecimal(100),2,RoundingMode.HALF_EVEN).add(newBigDecimal(1));returncurrentFileValue.divide(newBigDecimal((Math.pow(t.doubleValue(),p.doubleValue()))),2,RoundingMode.HALF_EVEN);}
ViniGodoy
Provavelmente sim.
C
christielencc
Existe alguma explicação para o cálculo ser diferente entre máquinas?
ViniGodoy
Sim. Primeiro, é preciso entender que números de ponto flutuante são naturalmente imprecisos em sua representação binária:
Devido a isso, fabricantes de hardware usam estratégias diferentes de arredondamento quando a imprecisão ocorre. Alguns usam registradores maiores, outros fazem calculos por firmware e pode sempre ter aqueles que mantém a imprecisão alta.
ViniGodoy
Existe um modificador do Java, chamado strictfp que pode ser usado sobre floats e doubles na tentativa de reduzir essa imprecisão. Ele força que a VM use a especificação do IEEE para fazer os calculos, desprezando o formato específico do processador (o que pode resultar em cálculos mais lentos, feitos por software). Você pode declarar um atributo ou classe com esse modificador (no caso da classe, ele valerá para todos os atributos e métodos floats da classe). Se eu não me engano, é possível ativar uma diretiva na VM que força calculos strictfp para todo programa também.