Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从数学运算中删除模?_Java_Modulo - Fatal编程技术网

Java 如何从数学运算中删除模?

Java 如何从数学运算中删除模?,java,modulo,Java,Modulo,我的教授不喜欢模的使用,因为它不够有效,但我不确定如何用逻辑运算符或其他方法得到相同的答案。有人能帮我解决这个问题吗 j = (j + 1) % a.length; 您可以这样做: j = j + 1; if (j >= a.length) { j = j - a.length; // assumes j was less than length before increment } @ajp提出了另一个实际可行的解决方案 j = j + 1; if (j >= a.le

我的教授不喜欢模的使用,因为它不够有效,但我不确定如何用逻辑运算符或其他方法得到相同的答案。有人能帮我解决这个问题吗

j = (j + 1) % a.length;
您可以这样做:

j = j + 1;
if (j >= a.length) {
    j = j - a.length; // assumes j was less than length before increment
}
@ajp提出了另一个实际可行的解决方案

j = j + 1;
if (j >= a.length) { // assumes j was less than length before increment
    j = 0; 
}
如果我在写代码,我会这样写,以防万一。它几乎没有额外的开销,并且消除了“假设”

当然,
%
也是一个很好的方法。除非有人是你的教授

这可能比除法/模法更快或更慢,这取决于跳转的成本(以及对指令管道/前瞻的任何影响)和整数除法指令的效率


旧处理器可能会在跳跃中做得更好。更现代的带有分隔的。这应该可以解决问题

 int k = a.length;
 int d = (j+1)/k;
 j = (j+1) - d*k

我能看到的没有模的唯一方法仍然不是很好:

j = (++j < a.length)? j : (j - a.length);

另外,我不完全确定Java如何处理循环预测,但至少在C中,如果可读性较低,那么下面的内容在速度方面会稍好一些,因为一般假设if语句的参数为true,并且
j
通常为true(除非
a.length想想你在这里做什么。你实际上是在说:

if j + 1 is smaller than a.length, set j to j + 1
otherwise, we set j to a value smaller than a.length

这个伪代码应该会给你一个非常清晰的解决方案的提示。

我同意教授的观点。教授的担忧没有充分的根据。除了一个特殊的应用,在许多语言中,模运算通常比条件跳转快,即使它慢一些,这种微优化仍然比条件跳转慢几个数量级磁盘访问或网络延迟。交换学校。或者在有新教授时下课。Modulo教授可以提供一些最优雅、高效和可读的代码。@Cruncher或与教授交谈,并参考这里的讨论和其他证据。是否对j和a.length有任何假设?否则我非常怀疑是否有人会我发现更快的代码。因为如果有;java就可以做到这一点。这个解决方案的问题是,在大多数系统上,/和%应该是相同的操作,只是存储结果的不同部分,所以它实际上根本不会改变速度。所以,如果教授讨厌一个模,他或她真的会讨厌一除一乘。Pr很可能这会比%慢?这并不重要,这都是荒谬的微观优化。我建议在你有时间的时候运行一些基准测试,以强化你的答案。注意:如果j在增量之前“小于”长度,你的条件将永远失败。你的意思是假设j也是:如果假设是正确的,那么你也可以说
if(j>=a.length)j=0;
。有时这会让事情变得更清楚。@LeeMeador,比如6502?我曾经为它们编写汇编语言。它们没有除法指令。如果这比使用模运算慢,你可能不会得到比现在更好的结果,除非你用特定的数字进行模运算(比如2的幂)很抱歉,试图阅读一条语句,其中对一个变量使用了预增量,您在同一语句中分配给该变量并在其他地方使用该变量,这让我很头疼。即使它有效。除非您使用APL编程,否则将所有内容都塞进一行是没有意义的。:)@ajb我可以把责任推到这一点上,这是我的主意。当时似乎是个好主意,但我明白你的意思。我担心我可能遗漏了一些东西,但是如果j很大,比如1000000?而a.length很小,比如5,j
有多大其实并不重要,只是它与
a.length
相比有多大。这(与大多数其他解决方案一样)假设
j
始终保持在
0
a.length
(包括排除)之间,因为如果不使用divmod操作或以其他方式(甚至更低效地)执行此类操作,则无法执行此操作。您所说的“小于a.length的值”是什么意思@理查丁格尔我认为他的意思是
一个a.length小于j的值
或者a.length小于j的某个因子,这样的值小于a.length
j++;
j = (j < a.length)? j : (j - a.length);
j++;
if (j >= a.length) {
    j -= a.length;
}
j++;
if(j < a.length) {
}
else {
    j -= a.length;
}
if j + 1 is smaller than a.length, set j to j + 1
otherwise, we set j to a value smaller than a.length