close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 13 years ago

Closed 13 years ago

Last modified 13 years ago

#1419 closed defect (fixed)

La función Round no redondea bien

Reported by: lmperez@… Owned by: Víctor de Buen Remiro
Priority: normal Milestone: Mantainance
Component: Kernel Version: 2.0.1
Severity: normal Keywords:
Cc:

Description

Hola TOL, la función round no redondea bien con algunos numeros reales y los decimales elegidos, os paso un ejemplo:

Real Round(0.008652760000000001,6);

Change History (4)

comment:1 Changed 13 years ago by Víctor de Buen Remiro

Resolution: fixed
Status: newclosed

Bienvenido al fabuloso mundo de la aritmética discreta. Lo que ocurre es que en realidad el número que esperas no existe en la aritmética de 64 bits que usamos en TOL, que es la que usa C y todos los programas en general. Es algo que depende de la arquitectura de la máquina pero pasa en todas de una forma u otra. Lo que se devuelve es el número más cercano al que debería ser y que es expresable en aritmética de 64 bits.

Si ejecutas este código podrás verlo más claro

Real Eval("0.008653")

En R pasa exactamente lo mismo, aunque para verlo hay que forzar la máxima precisión de salida

> sprintf("%.16g",round(0.008652760000000001,6))
[1] "0.008652999999999999"

comment:2 Changed 13 years ago by lmperez@…

¿Entonces no hay nada que podamos hacer?

comment:3 Changed 13 years ago by Víctor de Buen Remiro

Si lo que se pretende es escribir en algún fichero de tipo tabla .bst, .bdt, .bmt, ... , entonces no se trata de un problema de redondeo artimético sino de formato de texto, lo cual se puede resolver con el uso de PutRealFormat

Por ejemplo, el siguiente código escribirá un fichero "c:/tmp/x.bmt" con el número "0.008653"

Text PutRealFormat("%.6lf");
Matrix x = Constant(1,1,0.008652760000000001);
Set BMTFile([[x]],"c:/tmp/x.bmt");
Matrix x_ = Include("c:/tmp/x.bmt")[1];
Real MatDat(x_,1,1);

Una vez realizadas las operaciones deseadas recuérdese recobrar la máxima precisión pues esto podría afectar a operaciones de escritura posteriores causando problemas imprevisibles:

Text PutRealFormat("%.16lg");

comment:4 Changed 13 years ago by Víctor de Buen Remiro

El ticket #1412 está relacionado en cierta forma con éste.

Note: See TracTickets for help on using tickets.