Código
Verás que imprime 0.5 sin problemas. Pero ahora, incrementale la precisión de impresión:
Código
Ahora hemos imprimido 0.5 con una precisión de 20 cifras decimales, y seguramente verás un valor como: 0.05000000000000000278. Es decir, en realidad `0.5` representa a un número un poquito más grande, ya que es imposible garantizar precisión exácta cuando se tratan de números flotantes (verás, de todas formas, que el error es muy muy muy pequeño).
Pues eso es fundamentalmente lo que te está pasando, que esas diferencias de precisión te están jugando una mala pasada. En el caso concreto de 1.55, si imprimes el valor que `scanf` ha leído:
Código
float n;
Te imprimirá algo como: 1.54999995231628417969 (un valor ligeramente menor a 1.55; y por eso te devuelve 0 en la última división). Incrementar la precisión ayuda, pero no resuelve el problema:
Código
double n;
Ahora a mí me imprime algo como: 1.55000000000000004441 (un número ligeramente superior). Pero como verás, sigue sin ser exáctamente el mismo número.
Por otro lado, en ésta división (supón que `n` es `float` como en tu caso original):
Código
b05=n/0.50;
Si escribes un "literal de número flotante", como `0.50`, por defecto, dicho literal `0.50` tiene tipo `double`. Por tanto, `n` se transforma en un `double` antes de hacer la división. Luego, se hace una división entre `double`s y se transforma el valor en un entero para asignarlo a `b05`. Para realizar una división `float` y no `double`, debes especificar que tu literal lo es: `0.50f`, y así no habrá conversiones de `n`.
Ésta conversiones implícitas puede incrementar (¡o disminuir, no se sabe!) la precisión, añadiendo más caos al asunto.
Si la precisión es fija, trabaja con números enteros y te quitas de en medio a los flotantes, tal y como propuso engel lex:
Código
int main() { int b200,b100,b50,b20,b10,b5,b2,b1,b05,b01,b005; float naux; int n; n = naux * 100; b200=n/20000; n=n-20000*b200; b100=n/10000; n=n-10000*b100; // etc... b1=n/100; n=n-100*b1; b05=n/50; n=n-50*b05; b01=n/10; n=n-10*b01; b005=n/5; return 0; }
O, para rematar la faena, hazlo con un bucle:
Código
#include <stdio.h> int main() { float faux; int n, naux; unsigned i; n = faux * 100; int vec[] = { 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 10, 5 }; int prec[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2 }; for (i = 0; i < 11; ++i) { naux = n / vec[i]; n = n - vec[i] * naux; } return 0; }
Explicación de mi `printf`: Si yo en el `printf` pusiera algo como: "%f" sin más, se mostraría en la salida algo como:
Código
La cantidad de monedas de 200.000000 es 4 La cantidad de monedas de 100.000000 es 1 // etc... La cantidad de monedas de 0.050000 es 4
Por que por defecto, la precisión de un `printf` es de 6 cifras decimales. Para "personalizar" la precisión, existe el modificar `.*` que permite pasarle la precisión como parámetro, antes del número que quiero imprimir.
Por ese motivo, he creado otro vector, llamado `prec`, que indica la precisión que quiero para cada elemento de la lista (ninguna para los números mayores a 0.5, de 1 cifra para 0.5 y 0.1, y de dos para 0.05), y ya se imprime bonito:
Código
La cantidad de monedas de 200 es 4 La cantidad de monedas de 100 es 1 // etc... La cantidad de monedas de 0.05 es 4