C is able to express efficient code for bit-banging. But it's still ugly and hard to use.
Ada handles it better than any language I've seen. Types are abstract but can be given concrete realizations. A number can be defined as, for example, the range of 0 to 31. And optionally the compiler could be told to store that in bits 20 to 25 of a 32-bit word. Or non-consecutively, or out of order, or across multiple words. Just about any kind of bit reordering and packing is supported. With overflow checking and so on, too.
Take away idea is you should never be using shift and and/or bitwise operations. The compiler should translate (and also check that it fits and doesn't overlap) into the low level binary representation behind the scenes for you.
Depends on what you mean by excellent. It sucks by definition since it doesn't have generics. It's efficient though which in some sense makes it excellent.