![]() |
| |||||||
| Registrarse | Preguntas Frecuentes | Lista de Foreros | Calendario | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
![]() |
| | LinkBack | Herramientas | Desplegado |
| |||
| ¡Hola! yo recibo archivos los cuales contienen entre otras cosas números decimales en forma textual. Éstos los tengo que leer y convertir en números de doble presición. Aquí he visto que algúnos números no son tratados bién y que su prsición es errónea. Ejemplo: En el archivo están entre otras cosas los números 1282.225 y 4.31. Yo leo estos números y los convierto en doble presición con "atof" o "strtod". Después de convertir éstos obtengo lo siguiente: 1282.225 se interpreta como 1282.2249999999999 y 4.31 como 4.3099999999999996 Lo peor del caso es que tengo que trabajar con dos decimales después de la coma y esto me trae bastantes problemas. Esto lo hago con el algoritmo siguiente: double _dFMT_NumberRound (double value, int nDigitsR) { return (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : 0.5)) / pow(10, nDigitsR)); } // nDigitsR == 2 (dos decimales después de la coma) 1282.225 me da 1282.22. Obvio que está mal. El algoritmo funciona en este caso bién, pero lamentablemente el valor a convertir ya estaba malo después de haber sido leído y convertido. Éste teendría que ser 1282.225. 4.31 también me dá problemas: Después de haber sido leido del archivo y convertido con "atof" su valor es 4.3099999999999996. Al tomar este valor como ingreso para el algoritmo, pasa lo siguiente (lo cual lo muestro en tres pasos): value * pow(10, nDigitsR) == 430.99999999999994 (int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : 0.5) == 431.00000000000000 (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : 0.5)) / pow(10, nDigitsR)) == 4.3099999999999996 En otras palabras: 431.00000000000000 / 100 = 4.3099999999999996 Como pueden ver, no solamente tengo un problema al convertir con atof o strtod, sino que también con una simple división por 100. ¿Podría alguien explicarme esta situación y decirme que es lo que puedo hacer para solucionarla? Yo trabajo con "MS Visual Studio .NET 2003" ¡Un millón de gracias! René |
| | ||||
| ||||
| |
| |||
| No hay tu tía. El pattern del double para 4.3099999999999996 es el mismo que para 4.31 y, por decir algo 4.3100000000000002. Todos esos valores son buenos, todos son correctos. El chabón simplemente te muestra el menor. Él desconoce cuál es el más "bueno". Para tu propósito deberías usar algún tipo de dato de punto fijo, algún currency o cosa así. O directamente con enteros y atender no los resultados de la división sino sus remanentes. Digo, seguro alguien ya te va a aconsejar alguna biblioteca que hace esto... pero el tipo de datos que estás usando no sirve para esto. Selaví. -- Todo bien. |
| |||
| No hay tu tía. El pattern del double para 4.3099999999999996 es el mismo que para 4.31 y, por decir algo 4.3100000000000002. Todos esos valores son buenos, todos son correctos. El chabón simplemente te muestra el menor. Él desconoce cuál es el más "bueno". Para tu propósito deberías usar algún tipo de dato de punto fijo, algún currency o cosa así. O directamente con enteros y atender no los resultados de la división sino sus remanentes. Digo, seguro alguien ya te va a aconsejar alguna biblioteca que hace esto... pero el tipo de datos que estás usando no sirve para esto. Selaví. -- Todo bien. |
| |||
| No hay tu tía. El pattern del double para 4.3099999999999996 es el mismo que para 4.31 y, por decir algo 4.3100000000000002. Todos esos valores son buenos, todos son correctos. El chabón simplemente te muestra el menor. Él desconoce cuál es el más "bueno". Para tu propósito deberías usar algún tipo de dato de punto fijo, algún currency o cosa así. O directamente con enteros y atender no los resultados de la división sino sus remanentes. Digo, seguro alguien ya te va a aconsejar alguna biblioteca que hace esto... pero el tipo de datos que estás usando no sirve para esto. Selaví. -- Todo bien. |
| |||
| René Ketterer Kleinsteuber wrote: > ¡Hola! > > yo recibo archivos los cuales contienen entre otras cosas números > decimales en forma textual. Éstos los tengo que leer y convertir en > números de doble presición. Aquí he visto que algúnos números no son > tratados bién y que su prsición es errónea. > > Ejemplo: > > En el archivo están entre otras cosas los números 1282.225 y 4.31. Yo > leo estos números y los convierto en doble presición con "atof" o > "strtod". Después de convertir éstos obtengo lo siguiente: > > 1282.225 se interpreta como 1282.2249999999999 > > y 4.31 como 4.3099999999999996 > > Lo peor del caso es que tengo que trabajar con dos decimales después > de la coma y esto me trae bastantes problemas. Esto lo hago con el > algoritmo siguiente: > > double _dFMT_NumberRound (double value, int nDigitsR) > { > return (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) > ? -0.5 : 0.5)) / pow(10, nDigitsR)); > } > > // nDigitsR == 2 (dos decimales después de la coma) > > > 1282.225 me da 1282.22. Obvio que está mal. El algoritmo funciona en > este caso bién, pero lamentablemente el valor a convertir ya estaba > malo después de haber sido leído y convertido. Éste teendría que ser > 1282.225. > > 4.31 también me dá problemas: Después de haber sido leido del archivo > y convertido con "atof" su valor es 4.3099999999999996. Al tomar este > valor como ingreso para el algoritmo, pasa lo siguiente (lo cual lo > muestro en tres pasos): > > value * pow(10, nDigitsR) == 430.99999999999994 > > (int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : 0.5) == > 431.00000000000000 > > (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : > 0.5)) / pow(10, nDigitsR)) == 4.3099999999999996 > > En otras palabras: > > 431.00000000000000 / 100 = 4.3099999999999996 > > Como pueden ver, no solamente tengo un problema al convertir con atof > o strtod, sino que también con una simple división por 100. > > ¿Podría alguien explicarme esta situación y decirme que es lo que > puedo hacer para solucionarla? Yo trabajo con "MS Visual Studio .NET > 2003" > > ¡Un millón de gracias! > > René A la explicación y soluciones aportadas por Hernán debo apuntarte lo siguiente para que te saques tus dudas: "What Every Computer Scientist Should Know About Floating-Point Arithmetic" http://www.eason.com/library/math/floatingmath.pdf Una versión condensada tipo presentación powerpoint la encuentras aqui: http://blogs.sun.com/darcy/resource/Wecpskafpa-ACCU.pdf Salu2 PD: Debo decir que tu inquietud es frecuente en foros de programación, asi como la bibligrafia que te he apuntado. -- Cholo Lennon Bs.As. ARG |
| |||
| René Ketterer Kleinsteuber wrote: > ¡Hola! > > yo recibo archivos los cuales contienen entre otras cosas números > decimales en forma textual. Éstos los tengo que leer y convertir en > números de doble presición. Aquí he visto que algúnos números no son > tratados bién y que su prsición es errónea. > > Ejemplo: > > En el archivo están entre otras cosas los números 1282.225 y 4.31. Yo > leo estos números y los convierto en doble presición con "atof" o > "strtod". Después de convertir éstos obtengo lo siguiente: > > 1282.225 se interpreta como 1282.2249999999999 > > y 4.31 como 4.3099999999999996 > > Lo peor del caso es que tengo que trabajar con dos decimales después > de la coma y esto me trae bastantes problemas. Esto lo hago con el > algoritmo siguiente: > > double _dFMT_NumberRound (double value, int nDigitsR) > { > return (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) > ? -0.5 : 0.5)) / pow(10, nDigitsR)); > } > > // nDigitsR == 2 (dos decimales después de la coma) > > > 1282.225 me da 1282.22. Obvio que está mal. El algoritmo funciona en > este caso bién, pero lamentablemente el valor a convertir ya estaba > malo después de haber sido leído y convertido. Éste teendría que ser > 1282.225. > > 4.31 también me dá problemas: Después de haber sido leido del archivo > y convertido con "atof" su valor es 4.3099999999999996. Al tomar este > valor como ingreso para el algoritmo, pasa lo siguiente (lo cual lo > muestro en tres pasos): > > value * pow(10, nDigitsR) == 430.99999999999994 > > (int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : 0.5) == > 431.00000000000000 > > (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : > 0.5)) / pow(10, nDigitsR)) == 4.3099999999999996 > > En otras palabras: > > 431.00000000000000 / 100 = 4.3099999999999996 > > Como pueden ver, no solamente tengo un problema al convertir con atof > o strtod, sino que también con una simple división por 100. > > ¿Podría alguien explicarme esta situación y decirme que es lo que > puedo hacer para solucionarla? Yo trabajo con "MS Visual Studio .NET > 2003" > > ¡Un millón de gracias! > > René A la explicación y soluciones aportadas por Hernán debo apuntarte lo siguiente para que te saques tus dudas: "What Every Computer Scientist Should Know About Floating-Point Arithmetic" http://www.eason.com/library/math/floatingmath.pdf Una versión condensada tipo presentación powerpoint la encuentras aqui: http://blogs.sun.com/darcy/resource/Wecpskafpa-ACCU.pdf Salu2 PD: Debo decir que tu inquietud es frecuente en foros de programación, asi como la bibligrafia que te he apuntado. -- Cholo Lennon Bs.As. ARG |
| |||
| René Ketterer Kleinsteuber wrote: > ¡Hola! > > yo recibo archivos los cuales contienen entre otras cosas números > decimales en forma textual. Éstos los tengo que leer y convertir en > números de doble presición. Aquí he visto que algúnos números no son > tratados bién y que su prsición es errónea. > > Ejemplo: > > En el archivo están entre otras cosas los números 1282.225 y 4.31. Yo > leo estos números y los convierto en doble presición con "atof" o > "strtod". Después de convertir éstos obtengo lo siguiente: > > 1282.225 se interpreta como 1282.2249999999999 > > y 4.31 como 4.3099999999999996 > > Lo peor del caso es que tengo que trabajar con dos decimales después > de la coma y esto me trae bastantes problemas. Esto lo hago con el > algoritmo siguiente: > > double _dFMT_NumberRound (double value, int nDigitsR) > { > return (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) > ? -0.5 : 0.5)) / pow(10, nDigitsR)); > } > > // nDigitsR == 2 (dos decimales después de la coma) > > > 1282.225 me da 1282.22. Obvio que está mal. El algoritmo funciona en > este caso bién, pero lamentablemente el valor a convertir ya estaba > malo después de haber sido leído y convertido. Éste teendría que ser > 1282.225. > > 4.31 también me dá problemas: Después de haber sido leido del archivo > y convertido con "atof" su valor es 4.3099999999999996. Al tomar este > valor como ingreso para el algoritmo, pasa lo siguiente (lo cual lo > muestro en tres pasos): > > value * pow(10, nDigitsR) == 430.99999999999994 > > (int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : 0.5) == > 431.00000000000000 > > (double) ((int)(value * pow(10, nDigitsR) + ((value < 0 ) ? -0.5 : > 0.5)) / pow(10, nDigitsR)) == 4.3099999999999996 > > En otras palabras: > > 431.00000000000000 / 100 = 4.3099999999999996 > > Como pueden ver, no solamente tengo un problema al convertir con atof > o strtod, sino que también con una simple división por 100. > > ¿Podría alguien explicarme esta situación y decirme que es lo que > puedo hacer para solucionarla? Yo trabajo con "MS Visual Studio .NET > 2003" > > ¡Un millón de gracias! > > René A la explicación y soluciones aportadas por Hernán debo apuntarte lo siguiente para que te saques tus dudas: "What Every Computer Scientist Should Know About Floating-Point Arithmetic" http://www.eason.com/library/math/floatingmath.pdf Una versión condensada tipo presentación powerpoint la encuentras aqui: http://blogs.sun.com/darcy/resource/Wecpskafpa-ACCU.pdf Salu2 PD: Debo decir que tu inquietud es frecuente en foros de programación, asi como la bibligrafia que te he apuntado. -- Cholo Lennon Bs.As. ARG |
| |
| |
![]() |
| Herramientas | |
| Desplegado | |
| |
Temas Similares | ||||
| Tema | Autor | Foro | Respuestas | Último mensaje |
| NT en Dell Presicion 380 | Carlos Valero | Newsgroup microsoft.public.es.windowsnt | 0 | 14-10-2005 22:23:56 |
| Comprobación de argumentos junto strtod | Asile | Newsgroup es.comp.lenguajes.c | 12 | 03-10-2004 10:47:26 |
| Comprobación de argumentos junto strtod. | Asile | Newsgroup es.comp.lenguajes.c | 12 | 26-08-2004 13:20:38 |