2016-05-12 144 views
-1

我正在使用Math.pow()方法,並且得到的結果與我從計算器獲得的結果不同。Java math.pow()返回錯誤答案

我使用的代碼:

public static int getSum(int a, int b, int c, int d){ 
    return (int)(d*Math.pow(16.0,6.0)+c*Math.pow(16.0,4.0)+b*Math.pow(16.0,2.0)+a); 
} 

印刷

getSum(0,0,128,191) 

打印出2147483647 雖然谷歌計算器顯示3212836864.

是什麼原因造成的?

回答

0

java中整數的最大值是2,147,483,647。你應該保持它的雙倍值,並且Math.ceil()Math.floor()。你也可以將它轉換爲長整型值,因爲這是一個64位二進制整數。

3

2,147,483,647是int可以容納的最大值。如果你需要更大的數字,就像在這種情況下一樣,讓你的函數返回一個長整數。

3

Java int有能力存儲2^32,如果它是有符號的,一半用於負數。對於正數,可以存儲高達2^31 -1 = 2147483647。此任務需要更大的類型,請使用long,並且在簽名時最多可以存儲9 223 372 036 854 775 807

+0

哦,我忘了提及,2147483647是一個大屁股素數。這是人類直到1867年才知道的最大素數 – Anton

0

將您的代碼更改爲以下內容:int - > 32 bit(2^32 -1) 測試最大長度的簡單方法是System.out.println(Integer.MAX_VALUE); ==> 2147483647

public static Long getSum(int a, int b, int c, int d) { 
    return (long) (d * Math.pow(16.0, 6.0) + c * Math.pow(16.0, 4.0) + b * Math.pow(16.0, 2.0) + a); 
} 
5

我想補充說明現有的答案(例如,如果有人想知道爲什麼沒有整數溢出):

The spec 5.1.3下說。基本收縮轉換

在第一步驟中,浮點數會被轉換成一 長,如果T是長,或者爲int,如果T是字節,短,炭或int, 如下:

  • 如果浮點數是NaN(§4.2.3),轉換的第一步的結果是一個int或長0

  • 否則,如果浮點數不是無窮大,浮點值被四捨五入爲int eger值V,使用IEEE 754 round-to-zero模式(§4.2.3)將
    舍入爲零。然後
    有兩種情況:

    • 如果T是長,並且該整數值可表示爲第一步驟中的長,那麼結果是長值V.

    • 否則,如果這個整數值可以表示爲一個int,那麼第一步的結果是int值V.

  • 否則,以下兩種情況之一必須是真實的:

    • 值必須是太小(幅度大或負無窮大的負值),和的結果第一步是int或long類型的最小可表示值。

    • 該值必須太大(大數值的正數或正數的無窮大),第一步的結果是int或long類型的最大可表示值。

所以從Math.pow返回你的double值轉換爲最大可表示int(即Integer.MAX_VALUE)。

請注意,這部分特定於浮點數轉換。如果您的方法是例如定義爲(注意附加澆鑄到long

public static int getSum(int a, int b, int c, int d){ 
    // Casting twice doesn't make sense. It's just here for demonstration. 
    return (int)(long)(d*Math.pow(16.0,6.0)+c*Math.pow(16.0,4.0)+b*Math.pow(16.0,2.0)+a); 
} 

在spec中的相應部分將是

帶符號的整數的收縮轉換爲整數類型T 簡單地丟棄所有,但n個最低順序位,其中n是用於表示類型T的位的數量 。除了可能丟失關於數值的大小的信息,這可能導致 產生的值的符號不同於符號輸入價值。

而你的方法會返回-1082130422(又稱整數溢出)。