3 回答
TA贡献1784条经验 获得超7个赞
一点提示。如果在乘法(或求和)数字时出现意外的负值,主要是数字溢出:
private static int generateNo(int randomNo, int value) {
return (int)(((long)randomNo * value) % 256);
}
TA贡献1817条经验 获得超14个赞
Java 倾向于使用有符号余数,而不是通常表示模数的运算(欧几里得除法的非负余数)。幸运的是,对于 2 的幂,有一个非常简单的解决方法:使用 bitwise &。无论如何,这更容易考虑,因为它是对位的微不足道的操作,而不是复杂除法算法的结果。
例如:
private static int generateNo(int randomNo, int value) {
return randomNo * value & 255;
}
这不可能有负面结果,因为& 255保证只能设置结果的低 8 位,因此结果肯定在 [0..255] 范围内。
如果你想要结果的一些低位,那么首先让乘法换行是可以的,就像这里(最低的 8 位)。如果你想计算(x * y) MOD pwherep不是 2 的幂,它就不能正常工作,因为(在解决了 Java 的有符号余数之后)实际计算变成了(由于 wrapping)((x * y) MOD 2³²) MOD p。IFFp除以 2³²(即 iffp是不超过 2³² 的 2 的幂)然后简化为(x * y) MOD p.
或者使用更多位级别的视图:乘积的位是“完整”乘积的最低 32 位(两个 32 位整数的完整乘积有 64 位),当然如果我们只需要这些位(或一些它们的子集,例如最低的 8),那很好。但是,如果我们想要的结果取决于乘积的 32 个高位,那么显然我们需要计算这些位。 (x * y) MOD p其中p不是 2 的幂将取决于完整产品的所有位。
TA贡献1869条经验 获得超4个赞
17719*197920 = 3506944480
, 大于Integer.MAX_VALUE
.
因此,乘法超出了 int 的范围,结果为-788022816
.
因此,取模数会导致否定结果。
添加回答
举报