Java 为什么模3是低效的?
我有这个代码,这个代码叫做“高效”,因为它比模3更高效 但为什么模3是低效的?它在下面不做同样的操作吗?Java 为什么模3是低效的?,java,operators,modulo,Java,Operators,Modulo,我有这个代码,这个代码叫做“高效”,因为它比模3更高效 但为什么模3是低效的?它在下面不做同样的操作吗? 模运算的复杂性是什么 在汇编级,模是用指令DIV实现的,对于大的数字,它可能比使用逻辑运算、移位和分支慢 DIV指令(以及签名数字的对应IDIV) 给出商和余数(模)。DIV r16潜水32位 DX:AX中的数字乘以16位操作数,并将商存储在AX和 其余部分用DX表示 在汇编级,模是用指令DIV实现的,对于大的数字,它可能比使用逻辑运算、移位和分支慢 DIV指令(以及签名数字的对应IDIV)
模运算的复杂性是什么 在汇编级,模是用指令DIV实现的,对于大的数字,它可能比使用逻辑运算、移位和分支慢 DIV指令(以及签名数字的对应IDIV) 给出商和余数(模)。DIV r16潜水32位 DX:AX中的数字乘以16位操作数,并将商存储在AX和 其余部分用DX表示
在汇编级,模是用指令DIV实现的,对于大的数字,它可能比使用逻辑运算、移位和分支慢 DIV指令(以及签名数字的对应IDIV) 给出商和余数(模)。DIV r16潜水32位 DX:AX中的数字乘以16位操作数,并将商存储在AX和 其余部分用DX表示
该java代码不会转换为相同的机器代码。移位和and运算比本机代码中的模运算快。示例代码被解析为本机代码,并在每次需要时调用 这是一个证明
即使如此,您也不应该过度优化代码的可读性。优化应该只在关键组件上进行,并且在一切就绪之后进行,并且不仅在理论上,而且在实践中可以衡量其好处。java代码不会转换为相同的机器代码。移位和and运算比本机代码中的模运算快。示例代码被解析为本机代码,并在每次需要时调用 这是一个证明
即使如此,您也不应该过度优化代码的可读性。优化只应在关键组件上进行,并且在一切就绪后,不仅在理论上,而且在实践中可以衡量效益。渐进复杂性显然是相同的(它是恒定时间)。另一方面,模2很容易用二进制实现;模3稍微复杂一些 给定任何数字
n
,n%2
可以是0
或1
,因此您所要做的就是保留最后一位的值。您可以使用一个非常简单的二进制文件和:
n % 2 == n & 1
另一方面,如果执行n%3
,则所有有效答案都是(二进制)00
、01
和10
。请注意,现在答案跨越两位;但是,并非所有两位数字都有效(二进制11
不能是n%3
的结果)。因此,您需要执行额外的操作:
// 3DEC == 11BIN, so (n & 3) keeps the last two bits of n. You
// then have to ensure that these last two bits are not both 1.
n % 3 == n & 3, if (n & 3) != 3
我不知道模3是如何在硬件中实现的,但不管它是如何实现的,它都会比模2稍微复杂一些。尽管如此,认为软件中的模运算比硬件中已有的模运算更有效是愚蠢的。渐近复杂性显然是相同的(它是常数时间)。另一方面,模2很容易用二进制实现;模3稍微复杂一些 给定任何数字
n
,n%2
可以是0
或1
,因此您所要做的就是保留最后一位的值。您可以使用一个非常简单的二进制文件和:
n % 2 == n & 1
另一方面,如果执行n%3
,则所有有效答案都是(二进制)00
、01
和10
。请注意,现在答案跨越两位;但是,并非所有两位数字都有效(二进制11
不能是n%3
的结果)。因此,您需要执行额外的操作:
// 3DEC == 11BIN, so (n & 3) keeps the last two bits of n. You
// then have to ensure that these last two bits are not both 1.
n % 3 == n & 3, if (n & 3) != 3
我不知道模3是如何在硬件中实现的,但不管它是如何实现的,它都会比模2稍微复杂一些。也就是说,认为软件中的模运算比硬件中已有的模运算更有效是愚蠢的
它不做同样的操作吗
在下面
否,因为代码不正确:请使用输入尝试它,它将返回false
。但是21%3
是0
21
是0b10101
。这意味着链接算法在while循环之后有oddCtr=3
和evenCtr=0
。因为3!=0
算法返回false
它不做同样的操作吗
在下面
否,因为代码不正确:请使用输入尝试它,它将返回false
。但是21%3
是0
21
是0b10101
。这意味着链接算法在while循环之后有oddCtr=3
和evenCtr=0
。因为3!=0
算法返回false
你是在谈论关于这个问题的评论,它说这是“作弊”吗?如果以下两个都是真的,我会感到震惊(a)x%3==0
还不是最有效的(b)编译器不够聪明,如果不是的话,也不足以将它换成更快的版本。如果x%3
与方法的代码在机器级别上是相同的代码,我也会感到惊讶。为了好玩,我刚刚运行了一个快速的微基准测试,唯一一种改进的算法优于%
的情况是n==0
。。。对于n的其他值,对于n的较大值,您的算法会稍微慢一点(n=3)到10倍。如果您链接的代码正确,我将被支持:例如21=0b10101
,因此oddCtr
最终将为3,evenCtr
将为0。这是否意味着21不是3的倍数???你是在谈论关于这个问题的评论,它说这是“作弊”?如果以下两个答案都是正确的,我会感到震惊