鉴于模除法和整数除法密切相关,您可能会认为在一次操作中获取这两个值是有意义的。有没有具有这种功能的语言?
后续问题:对于不具备此功能的语言,是否最好通过减去除法 * 分母的结果来计算模数?
// 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;
Run Code Online (Sandbox Code Playgroud)
使用时BigInteger可以一次运算查询商和余数
BigInteger myNumber = BigInteger.valueOf(125), denominator = BigInteger.valueOf(6);\nBigInteger[] result = myNumber.divideAndRemainder(denominator);\nSystem.out.println(myNumber + " / " + denominator + " = " + result[0]);\nSystem.out.println(myNumber + " % " + denominator + " = " + result[1]);\nRun Code Online (Sandbox Code Playgroud)\n125 / 6 = 20\n125 % 6 = 5\nRun Code Online (Sandbox Code Playgroud)\n但是,当您使用整数值进行计算时,最好信任 JIT\xc2\xa0compiler/hotspot\xc2\xa0optimizer。
\n例如当我使用
\nstatic void test(int myNumber, int denominator) {\n int division = myNumber / denominator; // 20\n int modulo1 = myNumber % denominator; // 5\n\n // prevent over-optimization\n if(division != 20 || modulo1 != 5) throw new AssertionError();\n}\nRun Code Online (Sandbox Code Playgroud)\n并经常运行test(125, 6),我得到以下使用 JDK\xc2\xa011/x86 编译的本机代码
0x0000029f3ef97b2c: mov eax,edx\n 0x0000029f3ef97b2e: test r8d,r8d\n 0x0000029f3ef97b31: je 29f3ef97b63h ;*idiv {reexecute=0 rethrow=0 return_oop=0}\n ; - SO71326541::test@2 (line 23)\n\n 0x0000029f3ef97b33: cmp eax,80000000h\n 0x0000029f3ef97b38: jne 29f3ef97b42h\n 0x0000029f3ef97b3a: xor edx,edx\n 0x0000029f3ef97b3c: cmp r8d,0ffffffffh\n 0x0000029f3ef97b40: je 29f3ef97b46h\n 0x0000029f3ef97b42: cdq\n 0x0000029f3ef97b43: idiv eax,r8d\n 0x0000029f3ef97b46: mov r11d,edx\n 0x0000029f3ef97b49: cmp eax,14h\n 0x0000029f3ef97b4c: jne 29f3ef97b72h ;*if_icmpne {reexecute=0 rethrow=0 return_oop=0}\n ; - SO71326541::test@11 (line 27)\n\n 0x0000029f3ef97b4e: cmp edx,5h\n 0x0000029f3ef97b51: jne 29f3ef97b86h ;*if_icmpeq {reexecute=0 rethrow=0 return_oop=0}\n ; - SO71326541::test@16 (line 27)\nRun Code Online (Sandbox Code Playgroud)\n我们可以清楚地看到,这两个操作,myNumber / denominator已经myNumber % denominator融合成一条idiv指令了。
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |