Because, like most decimal fractions, these numbers can't be represented exactly by a binary floating point format. To see what values are actually being used:
#include <cstdio>
int main() {
printf("%.20f %.20f\n", .090, .003);
}
Output: 0.08999999999999999667 0.00300000000000000006
These small rounding errors mean that the first value is slightly less than an exact multiple of the second, hence the result you see.
You may want to allow a small tolerance for error:
if (r > y - some_small_value) {
r = 0;
}