【问题标题】:Does casting random integers to short give a uniform distribution?将随机整数转换为短整数会给出均匀分布吗?
【发布时间】:2016-10-21 16:45:32
【问题描述】:
正如标题所解释的,我希望生成一系列随机短值。因为没有 Random.nextShort() 函数,所以我想要做的最简单的方法似乎是将整数转换为短整数,使用:
Random rand = new Random(int seed);
(short) rand.nextInt()
但是,我不完全理解这种转换是如何发生的,因此我不能确定生成的短值仍然是随机的。是这样吗?提前致谢。
【问题讨论】:
标签:
java
random
casting
int
short
【解决方案1】:
int 的短转换通过按位截断来工作。只要整数是随机分布的,短值也应该是 - 是的。
来自 Java 语言规范5.1.3:
有符号整数到整数类型 T 的窄化转换
简单地丢弃除 n 个最低位之外的所有位,其中 n 是数字
用于表示类型 T 的位数。
int 有 32 位,short 有 16 位。本质上,转换与加(或减)65536(即 2 的 16 次方)相同,直到值在 @987654324 可表示的范围内@。因此,恰好有 65536 个 int 值映射到每个可能的 short 值。
【解决方案2】:
规范的方法是short result = (short)(rand.nextInt(Short.MAX_VALUE-Short.MIN_VALUE+1) + Short.MIN_VALUE)。这样做的原因是,您需要一个跨越 Short.MAX_VALUE-Short.MIN_VALUE+1 值并从 Short.MIN_VALUE 开始的范围内的数字。
简单的截断可能就足够short (如果速度对你很重要,它可能也更快),但这种方法适用于任何范围。
假设您想要一个介于-5 和12(包括两者)之间的随机数,然后您将调用rand.nextInt(12-(-5)+1)+(-5),或者如果您简化所有计算:rand.nextInt(18)-5。
【解决方案3】:
避免错误的好方法是:
Random rand = new Random(int seed);
short s = (short) rand.nextInt(Short.MAX_VALUE + 1);
如果你还需要负空:
short s = (short) rand.nextInt(Short.MAX_VALUE - Short.MIN_VALUE + 1) + Short.MIN_VALUE;
最快的解决方案:
short s = (short) random.nextInt(1 << 16); // any short
short s = (short) random.nextInt(1 << 15); // any non-negative short
【解决方案4】:
该数字仍然是随机的,但您可能会对此数字的不同最大值/最小值有问题,有关更多信息,请查看此处的第一个答案here
【解决方案5】:
我认为这行不通,因为int 比short 大很多。
只需随机取一个float 或double(值在[-1;1] 之间)并将它们乘以short 的最大值:
short i= (short) rand.nextFloat() * Short.MAX_VALUE;