Bueno, esto es un error en un código muy sencillo, del que me acabo de dar cuenta. Resulta que quiero multiplicar un número en coma flotante por 10 y asignarselo a un entero. Algo en teoría trivial, pero que requiere dos lineas de código para que salga el resultado que yo quiero:
La línea de arriba es la que yo ponía antes de detectar el error, y como veis, se pierde una décima en la operación. Las líneas de abajo funcionan bien.
Explicación:
Como veis, el error se produce porque la instrucción FLD carga el número -1.79899993896484375e+0002 en el coprocesador, en vez de -1799.0 y luego al pasarlo a entero con la función FISTP (que hay dentro de __ftol) se recortan los decimales y se jode una decima del número. Por defecto el copro siempre "recorta" en vez de "redondear".
En las instrucciones de abajo el error se corrige porque la instrucción FSTP redondea el número a -1799. INEXPLICABLEMENTE :o en la siguiente instrucción FLD se carga ST0 = -1.79900000000000000e+0003
Alguien me puede decir por qué en la primera operación FLD se carga ST0 = -1.79899993896484375e+0002 y en la segunda ST0 = -1.79900000000000000e+0003 ????
Tambien me gustaría saber si este código funciona igual en un K7, yo tengo un PIII. Solo teneis que copiar las 5 líneas en C para probarlo...
gracias y perdón por el tocho
un saludo
Código [Seleccionar]
int entero;
float flotante,angulo=-179.9;
entero=angulo*10; //Resultado de esta operación entero=-1798
flotante=angulo*10;
entero=flotante; //Resultado de esta operación entero=-1799
La línea de arriba es la que yo ponía antes de detectar el error, y como veis, se pierde una décima en la operación. Las líneas de abajo funcionan bien.
Explicación:
Código [Seleccionar]
entero=angulo*10;
fld dword ptr [angulo] // ST0 = -1.79899993896484375e+0002
fmul dword ptr [__real@41200000] // numero 10.0
call __ftol
mov dword ptr [entero],eax
flotante=angulo*10;
fld dword ptr [angulo] // ST0 = -1.79899993896484375e+0002
fmul dword ptr [__real@41200000] // numero 10.0
fstp dword ptr [flotante] // flotante=-1799.0
entero=flotante;
fld dword ptr [flotante] // ST0 = -1.79900000000000000e+0003
call __ftol
mov dword ptr [entero],eax
Como veis, el error se produce porque la instrucción FLD carga el número -1.79899993896484375e+0002 en el coprocesador, en vez de -1799.0 y luego al pasarlo a entero con la función FISTP (que hay dentro de __ftol) se recortan los decimales y se jode una decima del número. Por defecto el copro siempre "recorta" en vez de "redondear".
En las instrucciones de abajo el error se corrige porque la instrucción FSTP redondea el número a -1799. INEXPLICABLEMENTE :o en la siguiente instrucción FLD se carga ST0 = -1.79900000000000000e+0003
Alguien me puede decir por qué en la primera operación FLD se carga ST0 = -1.79899993896484375e+0002 y en la segunda ST0 = -1.79900000000000000e+0003 ????
Tambien me gustaría saber si este código funciona igual en un K7, yo tengo un PIII. Solo teneis que copiar las 5 líneas en C para probarlo...
gracias y perdón por el tocho
un saludo