为了账号安全,请及时绑定邮箱和手机立即绑定

Java MOD 运算符返回负值

Java MOD 运算符返回负值

吃鸡游戏 2022-01-12 16:56:39
我有这个方法:private static int generateNo(int randomNo, int value){    return   ((randomNo*value)%256);}在我的示例中 randomNo = 17719 qValue = 197920当我用计算器计算它时,返回的值应该是 224,但是,当我运行程序时它返回 -32。谁能解释一下。
查看完整描述

3 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

一点提示。如果在乘法(或求和)数字时出现意外的负值,主要是数字溢出:


private static int generateNo(int randomNo, int value) {

    return (int)(((long)randomNo * value) % 256);

}


查看完整回答
反对 回复 2022-01-12
?
大话西游666

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 的幂将取决于完整产品的所有位。


查看完整回答
反对 回复 2022-01-12
?
MMTTMM

TA贡献1869条经验 获得超4个赞

17719*197920 = 3506944480, 大于Integer.MAX_VALUE.

因此,乘法超出了 int 的范围,结果为-788022816.

因此,取模数会导致否定结果。


查看完整回答
反对 回复 2022-01-12
  • 3 回答
  • 0 关注
  • 206 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信