Cuando tú trabajas con números de precisión flotante, tienes que tener en cuenta bastantes cosas, pero por norma general, es como dice engel lex, problemas de precisión. Ejemplo bastante ilustrador:
Verás que imprime 0.5 sin problemas. Pero ahora, incrementale la precisión de impresión:
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:
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:
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):
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:
O, para rematar la faena, hazlo con un bucle:
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:
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 (c) [Seleccionar]
printf("%f", 0.5);
Verás que imprime 0.5 sin problemas. Pero ahora, incrementale la precisión de impresión:
Código (c) [Seleccionar]
printf("%.20f", 0.5);
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 (c) [Seleccionar]
float n;
scanf("%f",&n);
printf("%.20f", 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 (c) [Seleccionar]
double n;
scanf("%lf",&n);
printf("%.20f", 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 (c) [Seleccionar]
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 (c) [Seleccionar]
int main()
{
int b200,b100,b50,b20,b10,b5,b2,b1,b05,b01,b005;
float naux;
int n;
scanf("%f", &naux);
n = naux * 100;
b200=n/20000;
printf("La cantidad de billetes de 200 es : %d\n",b200);
n=n-20000*b200;
b100=n/10000;
printf("La cantidad de billetes de 100 es : %d\n",b100);
n=n-10000*b100;
// etc...
b1=n/100;
printf("La cantidad de billetes de 1 es : %d\n",b1);
n=n-100*b1;
b05=n/50;
printf("La cantidad de monedas de 0.50 es : %d\n",b05);
n=n-50*b05;
b01=n/10;
printf("La cantidad de monedas de 0.10 es : %d\n",b01);
n=n-10*b01;
b005=n/5;
printf("La cantidad de monedas de 0.05 es : %d\n",b005);
system("pause");
return 0;
}
O, para rematar la faena, hazlo con un bucle:
Código (c) [Seleccionar]
#include <stdio.h>
int main()
{
float faux;
int n, naux;
unsigned i;
scanf("%f", &faux);
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];
printf("La cantidad de monedas de %.*f es %d\n", prec[i], vec[i] / 100.0, naux);
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 (c) [Seleccionar]
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 (c) [Seleccionar]
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