1. 程式人生 > >深入思考:java如何求兩個資料型別為int的數的平均數

深入思考: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. 同號採用 情況1 的公式程式設計,需要判斷兩個數的大小;
  3. 異號採用 情況2 的公式程式設計;
  4. 檢驗測試編寫是否正確。

程式碼如下:

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”