C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 29:
[29.12] What's the point of the L, U and f suffixes on numeric literals?

You should use these suffixes when you need to force the compiler to treat the numeric literal as if it were the specified type. For example, if x is of type float, the expression x + 5.7 is of type double: it first promotes the value of x to a double, then performs the arithmetic using double-precision instructions. If that is what you want, fine; but if you really wanted it to do the arithmetic using single-precision instructions, you can change that code to x + 5.7f. Note: it is even better to "name" your numeric literals, particularly those that are likely to change. That would require you to say x + crateWeight where crateWeight is a const float that is initialized to 5.7f.

The U suffix is similar. It's probably a good idea to use unsigned integers for variables that are always >= 0. For example, if a variable represents an index into an array, that variable would typically be declared as an unsigned. The main reason for this is it requires less code, at least if you are careful to check your ranges. For example, to check if a variable is both >= 0 and < max requires two tests if everything is signed: if (n >= 0 && n < max), but can be done with a single comparison if everything is unsigned: if (n < max).

If you end up using unsigned variables, it is generally a good idea to force your numeric literals to also be unsigned. That makes it easier to see that the compiler will generate "unsigned arithmetic" instructions. For example: if (n < 256U) or if ((n & 255u) < 32u). Mixing signed and unsigned values in a single arithmetic expression is often confusing for programmers — the compiler doesn't always do what you expect it should do.

The L suffix is not as common, but it is occasionally used for similar reasons as above: to make it obvious that the compiler is using long arithmetic.

The bottom line is this: it is a good discipline for programmers to force all numeric operands to be of the right type, as opposed to relying on the C++ rules for promoting/demoting numeric expressions. For example, if x is of type int and y is of type unsigned, it is a good idea to change x + y so the next programmer knows whether you intended to use unsigned arithmetic, e.g., unsigned(x) + y, or signed arithmetic: x + int(y). The other possibility is long arithmetic: long(x) + long(y). By using those casts, the code is more explicit and that's good in this case, since a lot of programmers don't know all the rules for implicit promotions.