Precisión de coma flotante C ++ [duplicado]

Posible duplicado:
Ejemplos de inexactitud de punto flotante

double a = 0.3;
std::cout.precision(20);
std::cout << a << std::endl;

resultado: 0.2999999999999999889

double a, b;
a = 0.3;
b = 0;
for (char i = 1; i <= 50; i++) {
  b = b + a;
};
std::cout.precision(20);
std::cout << b << std::endl;

resultado: 15.000000000000014211

Entonces ... 'a' es más pequeño de lo que debería ser. Pero si tomamos 'a' 50 veces, el resultado será más grande de lo que debería ser.

¿Por qué es esto? ¿Y cómo obtener el resultado correcto en este caso?