[C con Clase] decimales en float

Salvador Pozo salvador en conclase.net
Dom Dic 10 14:56:06 CET 2006


El pasado 2006-12-10 08:49:21, Rafael Román Otero escribió:
 
RRO> hola, estoy haciendo un sencillo programita y en parte de él necesito saber cuando un numero introducido  con scanf es multiplo de 'pi' (tomandolo como 3.1416). lo que se me habia ocurrido era hacer esto: 

Hola:

Lo primero que quiero aclarar es que el operador % sólo está definido para números enteros. Esto ya lo has descubierto tu mismo, pero no está de más aclararlo.

No tiene sentido calcular el resto de una división entre números con decimales, ya que el resultado de tal división debe tener decimales.

La solución que has probado no funcionará casi nunca por el modo en que se codifican los números en coma flotante.

Estos números no tienen gran precisión a partir del segundo o tercer decimal, ya que sólo usan un número relativamente pequeño de bits para la mantisa. Los números en coma flotante se almacenan en la forma:
mantisa x 2^(exponente)

En un valor de 16 bits (generalmente usado para float), parte de los bits se usan para la mantisa (creo que 11), y el resto para el exponente. 

No es lógico pensar que con 11 bits podamos obtener precisiones de cuatro o más decimales, salvo para números muy pequeños.

Para evitar esto podrías usar el formato double o long double, pero esto sólo traslada el problema a números mayores.

Una solución que se me ocurre es trabajar con márgenes de error. Puedes tomar la parte decimal de la división entre dos números y compararla con un valor predeterminado, digamos una centésima: 0.01, si el error es menor, consideras que el número es un múltiplo, si es mayor, que no lo es.

También puedes usar la función fmod, de la librería estándar math de C:

http://c.conclase.net/librerias/funcion.php?fun=fmod

Pero esta función raramente te dará un valor cero como retorno, de modo que también tendrás que verificar que el valor devuelto está en un margen determinado, por ejemplo, mayor o igual 0.99 y menor o igual que 0.01.

Si te interesa aproximar hasta el cuarto decimal tendrás que disminuir ese error hasta 0.0001, y desde luego, trabajar con double o incluso con long double.

Hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net


Más información sobre la lista de distribución Cconclase