Instead of multiplying by 1.0, you can just quit. It seems to me more pure and understandable. First, it clearly indicates which type of data you want to use. You can be quite happy with the accuracy of the approximations float4or float8, rather than pay the extra cost for accurate calculations numeric.
SELECT COUNT(*)::float / (SELECT COUNT(name)
FROM x
WHERE d = '0')::float
FROM x, y
WHERE x.a = y.a AND x.b = '0'
GROUP BY y.c
ORDER BY y.c ASC
test = # select 1.0 * 5/10;
? column?
------------------------
0.50000000000000000000
(1 row)
test=# select pg_typeof(1.0 * 5 / 10);
pg_typeof
-----------
numeric
(1 row)
test=# select 5::float / 10::float;
?column?
----------
0.5
(1 row)
test=# select pg_typeof(5::float / 10::float);
pg_typeof
------------------
double precision
(1 row)