簡體   English   中英

Math.pow()使用不同的輸入返回相同的結果

[英]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]確實是每次迭代的下一個值,它是。 我是否遺漏了與使用intMath.pow()

encryptedBlocks[i]dn前兩個迭代值:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM