[英]Math.pow() returning same result with different inputs
我有兩個空數組和一些變量:
static int p = 41;
static int q = 67;
static int d = 83;
static int n = p * q;
static int[] encryptedBlocks = new int[charArray.length];
static int[] decryptedArray = new int[charArray.length];
第一個填充了以下內容(我已經檢查過,它是):
1573
1978
385
1092
1022
857
856
1387
225
606
2293
1339
1630
第二個數組我試圖在for循環中填充方程的結果:
for (int i = 0; i < encryptedBlocks.length; i++) {
int M = (int)Math.pow(encryptedBlocks[i], d) % n;
decryptedArray[i] = M;
}
問題是,我得到了相同的結果為M
為每次迭代...我為正在發生的事情完全無知:
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
萬一我已經雙重檢查encryptedBlocks[i]
確實是每次迭代的下一個值,它是。 我是否遺漏了與使用int
和Math.pow()
?
encryptedBlocks[i]
, d
和n
前兩個迭代值:
1573 83 2747
1978 83 2747
在你的代碼行中
int M = (int)Math.pow(encryptedBlocks[i], d) % n;
您正在計算Math.pow(encryptedBlocks [i],d),然后將其轉換為int,然后在int結果上使用modulo m。 您可能想要做的只是在完成所有數學運算后才轉換為int:
int M = (int) (Math.pow(encryptedBlocks[i], d) % n);
產量:
1147 2564 1457 2351 2414 982 1073 2480 923 1526 704 427 235
對於給定的輸入數據。
如前所述這里 :
演員優先於分裂操作
因此,正如我在評論中提到的,你必須替換它:
int M = (int)Math.pow(encryptedBlocks[i], d) % n;
有了這個:
int M = (int)(Math.pow(encryptedBlocks[i], d) % n);
只是優先級錯誤
改變這個int M = (int)Math.pow(encryptedBlocks[i], d) % n;
至
int M = (int)(Math.pow(encryptedBlocks[i], d) % n);
是的,您將提前轉換為int,這導致輸出始終相同。 您可以在以下輸出中查看此內容。
package test;
public class MathPow {
static int p = 41;
static int q = 67;
static int d = 83;
static int n = p * q;
static int[] encryptedBlocks = {1573,
1978,
385,
1092,
1022,
857,
856,
1387,
225,
606,
2293,
1339,
1630};
static int[] decryptedArray = new int[13];
public static void main (String []args){
for (int i = 0; i < encryptedBlocks.length; i++) {
double power = Math.pow(encryptedBlocks[i], d);
System.out.println("Power : "+power);
double pwer = power % n;
int M = (int)pwer;
decryptedArray[i] = M;
System.out.println("M : "+M);
}
}
}
在最后完成轉換為int時的輸出。
Power : 2.1305119658955046E265
M : 1147
Power : 3.8617294369074443E273
M : 2564
Power : 3.9195891716526933E214
M : 1457
Power : 1.4875753889539146E252
M : 2351
Power : 6.087295034019223E249
M : 2414
Power : 2.7378409793777127E243
M : 982
Power : 2.4849775423187883E243
M : 1073
Power : 6.199351610800489E260
M : 2480
Power : 1.702742606656262E195
M : 923
Power : 8.815111415893474E230
M : 1526
Power : 8.194765730142982E278
M : 704
Power : 3.332636081546012E259
M : 427
Power : 4.0885674380373943E266
M : 235
並且在Math.pow操作之后完成轉換時輸出。
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
您可以看到功率運算結果相同,因此M也相同。
電源操作的結果太大而不能存儲在整數中。 1573 ^ 83
單獨是一個122位數字,你在計算功率后進行mod操作,所以它已經溢出。
如果不考慮性能,可以使用BigInteger類。 這應該工作:
BigInteger bigN = BigInteger.valueOf(n);
for (int i = 0; i < encryptedBlocks.length; i++) {
BigInteger M = BigInteger.valueOf(encryptedBlocks[i]).pow(d).mod( bigN );
decryptedArray[i] = Integer.valueOf(M.toString());
}
for(int i : decryptedArray) System.out.println(i);
但是, BigInteger
操作有點慢。 如果您更喜歡更快的解決方案,您可以實現自己的電源功能,這樣您就可以在接近溢出整數值時執行mod操作。
您的問題在括號中。 這是編譯器看到你寫的內容的方式:
((int) Math.pow(encryptedBlocks[i], d)) % n
這是微妙的,但發生的事情它轉換成一int
取模前。 通常情況下,這不會產生任何影響,但在您的情況下, Math.pow
返回如此大的數字,將其轉換為int
將其截斷為2147483647
int可以存儲的最大值,然后它將采用將要存儲的模塊返回2662
。
現在,要獲得正確答案,我們需要做的就是確保它首先計算模數:
(int) (Math.pow(encryptedBlocks[i], d) % n)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.