Refactor rand(range, a) methods with more efficient implementation

``rand(rgn)`` requires first computing the maximum multiple of ``length(rgn)`` (as ``div(typemax(T), k) * k``). This value is fixed given an ``rgn``. 

Therefore, when we do ``rand(rgn, n)``, we can compute this value at the beginning instead of computing it at each iteration (which causes considerable slow down). This patch introduces a ``RandU`` type to capture this information, which also makes codes concise.

My benchmark shows that this patch increases the throughput of ``rand!(run, a)`` by about 60% - 80%.