[英]Best way to get both modulo and result of division?
Seeing as modulo and integer division are closely related, you'd think it would make sense to get both values in one operation.鉴于模和 integer 除法密切相关,您会认为在一次操作中获得这两个值是有意义的。 Are there languages that have this capability?
有没有具有这种能力的语言?
Follow up question: For languages that don't have this capability, is it best to compute the modulo by subtracting off the result of the division * denominator?跟进问题:对于没有这种能力的语言,最好通过减去除法 * 分母的结果来计算模数吗?
// In java, if I want both values I need to do this:
int myNumber = 125;
int denominator = 6;
int division = myNumber / denominator; // 20
int modulo1 = myNumber % denominator; // 5
// Follow up: Is this a more efficient way to compute the modulo?
int modulo2 = myNumber - division * denominator;
When you use BigInteger
, you can query quotient and remainder in one operation当您使用
BigInteger
时,您可以一次查询商和余数
BigInteger myNumber = BigInteger.valueOf(125), denominator = BigInteger.valueOf(6);
BigInteger[] result = myNumber.divideAndRemainder(denominator);
System.out.println(myNumber + " / " + denominator + " = " + result[0]);
System.out.println(myNumber + " % " + denominator + " = " + result[1]);
125 / 6 = 20
125 % 6 = 5
However, when you are calculating with integral values, it's best to trust the JIT compiler/ hotspot optimizer.但是,当您使用整数值进行计算时,最好信任 JIT 编译器/热点优化器。
Eg when I use例如当我使用
static void test(int myNumber, int denominator) {
int division = myNumber / denominator; // 20
int modulo1 = myNumber % denominator; // 5
// prevent over-optimization
if(division != 20 || modulo1 != 5) throw new AssertionError();
}
and run test(125, 6)
often enough, I get the following compiled native code with JDK 11/x86并经常运行
test(125, 6)
,我得到以下使用 JDK 11/x86 编译的本机代码
0x0000029f3ef97b2c: mov eax,edx
0x0000029f3ef97b2e: test r8d,r8d
0x0000029f3ef97b31: je 29f3ef97b63h ;*idiv {reexecute=0 rethrow=0 return_oop=0}
; - SO71326541::test@2 (line 23)
0x0000029f3ef97b33: cmp eax,80000000h
0x0000029f3ef97b38: jne 29f3ef97b42h
0x0000029f3ef97b3a: xor edx,edx
0x0000029f3ef97b3c: cmp r8d,0ffffffffh
0x0000029f3ef97b40: je 29f3ef97b46h
0x0000029f3ef97b42: cdq
0x0000029f3ef97b43: idiv eax,r8d
0x0000029f3ef97b46: mov r11d,edx
0x0000029f3ef97b49: cmp eax,14h
0x0000029f3ef97b4c: jne 29f3ef97b72h ;*if_icmpne {reexecute=0 rethrow=0 return_oop=0}
; - SO71326541::test@11 (line 27)
0x0000029f3ef97b4e: cmp edx,5h
0x0000029f3ef97b51: jne 29f3ef97b86h ;*if_icmpeq {reexecute=0 rethrow=0 return_oop=0}
; - SO71326541::test@16 (line 27)
We can clearly see that the two operations, myNumber / denominator
and myNumber % denominator
have been fused into a single idiv
instruction.我们可以清楚地看到,
myNumber / denominator
和myNumber % denominator
这两个操作已融合到一条idiv
指令中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.