深入思考:java如何求兩個資料型別為int的數的平均數
一 . 遇到的問題:
我最初通過eclipse軟體設計如下方法:
public static double foraverage(int a,int b) {
double c=(double)(a+b)/2;
return c;
}
但在測試過程中發生瞭如下問題:
public static void main(String[] args) {
double average=foraverage(1000000000, 2000000000);
System.out.println(average);
}
得到結果為:-6.47483648E8
二 . 問題分析:
1 . 主要原因:
雖然寫入兩個 int 值 a 和 b,但是當執行“a+b” 命令產生的結果可能超過int的邊界([-2147483648,2147483647]),造成了精度損失,所以輸出了一個負數。
2 . 解決辦法:
根據 int 的邊界是雙邊的,所以需要分為兩種情況來考慮:
情況1:給出兩個數值為同號
如果為同號的兩個數,相加可能出現超出邊界情況,所以需要對平均數計算方程需進行如下改動:average=min+(max-min)/2 或者 average=max-(max-min)/2。
情況2:給出兩個數值為異號
此時,不論兩個陣列值在[-2147483648,2147483647]範圍內取多少,average=(max+min)/2
綜上,本題的程式設計思路如下:
- 判斷所求兩個數為 同號 還是 異號,使用 異或(^) 進行判斷;
- 同號採用 情況1 的公式程式設計,需要判斷兩個數的大小;
- 異號採用 情況2 的公式程式設計;
- 檢驗測試編寫是否正確。
程式碼如下:
public static double foraverage(int min,int max) {
double average=0;
if((min^max)>0) {
if(min>max) {
min=min^max;
max =max^min;
min=min^max;
}
average=min+(double)(max-min)/2;
}else {
average=(double)(max+min)/2;
}
return average;
}
經檢驗,程式成功完成任務目標。
三 . 總結與反思:
1 .反思:
在今後的程式設計過程中,應該仔細思考,不能因為任務簡單而掉以輕心。本題看似提問“如何求平均數”,而實際上考察了 int 型別數值的取值範圍、如何不使用乘法判斷兩個數字是否為同號、if 語句的掌握與應用等多方面知識。所以在今後的程式設計中,越是簡單的細節,越要注意題目是否題中有題,話裡有話。儘可能考慮所有可能出現的問題與bug,細節決定成敗。
2.總結:通過本題,我學到了如下知識:
a.基本資料型別的取值範圍
- byte:[-2^7 , 2^7-1]
- short:[-2^15 , 2^15-1]
- int:[-2^31 , 2^31-1]
- long:[-2^63 , 2^63-1]
- float:[2-149 , 2^128-1]
- double:[2^-1074 ,2^1024-1]
b.如何不使用乘法進行同號異號判斷:
在有些情況中,使用乘法判斷同號異號可能造成數值超出資料型別的取值範圍,所以以後統一通過異或的方法判斷兩個數字是同號還是異號。
例:判斷數值a和數值b是否為同號?
方法:
如果 a^b>0,則判斷兩個數字為同號或者至少一個數字為0
如果a^b<0,則判斷兩個數字為異號。
c.一些小技巧:
- 進行除法運算時,可以通過位運算,且位運算速度更快。
int a=4;
System.out.println(a>>1);// 等價於“a/2”
- 異或的活用:異或除了可以用於計算是否同號之外,還可以用來進行數值交換,交換方式:
int x=5;int y=6;
x=x^y;
y=y^x;
x=x^y;
System.out.println(x+","+y);// 輸出結果為“6,5”