Consider following statement:
byte by = 5; //works fine
literal \'5\' is of type int and small enough to fit into a variable of type byt
The easy answer is, because the specification says so (compile-time constants of type integer can be assigned to smaller types as long as they fit).
With floating-point however, there is not so much determining whether the constant fits, but rather the loss of precision that comes along with it. E.g. assigning 1.23456789123 to a double is fine, but to a float is not. It's not so obvious why, in this case, though, at least to some programmers. I'd definitely count it as a surprise when some floating-point constants work while others won't and the reason isn't as clear as with integral types (where the limits are often second nature to most).
Note that even with doubles there sometimes is lost information. You can make your constants as precise as you want, but you won't always get the exact value you stated in the variable.