程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> JAVA基礎之三:運算操作符

JAVA基礎之三:運算操作符

編輯:JAVA綜合教程

JAVA基礎之三:運算操作符


\

 

本文中主要介紹Java中的運算操作。 如何正確的使用運算符,防止溢出是每個程序員的責任。

1. 算術運算

Java支持以下的算術運算:

運算符 描述 使用 例子 * 乘法 expr1*expr2 2 * 3 → 6
3.3 * 1.0 → 3.3 / 除法 expr1/expr2 1 / 2 → 0
1.0 / 2.0 → 0.5 % 取余 expr1%expr2 5 % 2 → 1
-5 % 2 → -1
5.5 % 2.2 → 1.1 + 加法(正號) expr1+expr2
+expr 1 + 2 → 3
1.1 + 2.2 → 3.3 - 減法(負號) expr1-expr2
-expr 1 - 2 → -1
1.1 - 2.2 → -1.1

2. 算術表達式

對於下面的表達式:

\

轉化為編碼(1+2*a)/3 + (4*(b+c)*(5-d-e))/f - 6*(7/g+h),需要注意的不能省略乘號(*)。

優先級:
  • 乘法(*),除法(/)和取余(%)優先於加法(+)和減法(-)運算,例如1+2*3-4/2可以表示為1+(2*3)-(4/2)。
  • 正號(+)和負號(-)擁有更高級別。
  • 括號()擁有最高級別,常用來調整運算順序。
  • 對於同級別運算符號,表達式結果從左到右計算,例如1+2-3+4等價於((1+2)-3)+4,1*2%3/4等價於((1*2)%3)/4。

    3. 混合類型運算

    算術運算僅適用於基本類型:byte, short, int, long, float, double和char,其中不包括boolean。

    如果兩個操作數的類型是int/long/float/double, 運算操作會直接使用此類型進行計算,例如int 5 + int 6 → int 11;double 2.1 + double 1.2 → double 3.3。

    值得注意的是對於int的除法運算,計算結果會被截斷,例如1/2 → 0而不是0.5。

    如果兩個操作數的類型是byte,short或者char,運算操作會使用int類型進行計算,char會被轉化為16位無符號整數,例如byte 127 + byte 1 → int 127 + int 1 → int 128。
    如果兩個操作數屬於不同的類型,較小的類型會被隱式的轉換成較大的類型,運算操作會使用較大的類型進行計算。

    舉例說明:
    • int/double → double/double → double,1/2 → 0, 1.0/2.0 → 0.5, 1.0/2 → 0.5, 1/2.0 → 0.5。
    • char + float → int + float → float + float → float。
    • 9 / 5 * 20.1 → (9 / 5) * 20.1 → 1 * 20.1 → 1.0 * 20.1 → 20.1(你可能不會想到這個答案)。
    • byte 1 + byte 2 → int 1 + int 2 → int 3(結果是int,不是byte)。

      二元運算操作對於類型的轉換概括如下:

      • 如果其中一個操作數是double,另一個操作數默認轉為double。
      • 如果其中一個操作數是float,另一個操作數默認轉為float。
      • 如果其中一個操作數是long,另一個操作數默認轉為long。
      • 其余的操作數默認的轉為int。

        一元運算操(正號、負號)對於類型的轉換概括如下:

        • 如果操作數是double,float,long或者int,不需要轉換。
        • 其余的如果是byte,short或char,會默認轉換為int。
          舉例說明:
          byte b1 = 1;
          byte b2 = -b1;  // 編譯會出錯, 因為-b1會返回int,不能轉換成byte
          
          取余運算符

          為了計算余數會重復的運行減法運算,直到差值的絕對值小於右操作數的絕對值,舉例說明:

          • -5 % 2 ? -3 % 2 ? -1
          • 5.5 % 2.2 ? 3.3 % 2.2 ? 1.1
            指數

            在Java中是沒有指數運算符的,你看到的'^'運算符是異或,不過你可以使用Math.exp(X,Y)進行指數的運算。

            4. 向上溢出/向下溢出

            研究下面的代碼並解釋輸出輸出:

            /*
             * "int"溢出說明
             */
            public class OverflowTest {
                public static void main(String[] args) {
                // int取值范圍[-2147483648, 2147483647]
                int i1 = 2147483647;           // int最大值
                System.out.println(i1 + 1);    // -2147483648 (溢出)
                System.out.println(i1 + 2);    // -2147483647
                System.out.println(i1 * i1);   // 1
            
                int i2 = -2147483648;          // int最小值
                System.out.println(i2 - 1);    // 2147483647 (溢出)
                System.out.println(i2 - 2);    // 2147483646
                System.out.println(i2 * i2);   // 0
                }
            }

            對於運算過程中的溢出,Java不會發出錯誤或者警告信息,但會產生不正確的結果。
            另一方面整數除法會產生截斷的整數,我們稱之為向下溢出,例如1/2→ 0,而不是0.5。
            做為程序員你有責任去檢查編程中的溢出。
            這時候我們也許會問,為什麼計算機不去標記溢出?由於歷史的原因, 當時處理器很慢,檢查溢出會消耗性能。

            5. 類型轉換

            在Java中,如果將double或float數據賦值給int變量會產生編譯錯誤。

            double d = 3.5;
            int i;
            i = d;            // 編譯錯誤
            int sum = 55.66f; // 編譯錯誤
            顯示類型轉換和類型轉換

            double賦值給int變量,你需要使用顯示類型轉換,形式為(int)value,返回的結果是被截斷的int數據,舉例說明:

            double d = 3.5;
            int i;
            i = (int) d;    // 將double類型的3.5轉換成int類型的3,之後賦值給i

            類型轉換只需要一個操作數,Java中有兩種類型轉換:

            • 以(new-type)操作數的形式進行顯示類型轉換。
            • 如果沒有精度缺失,編譯器自動的會進行隱示類型轉換。
               
              int i = 3;
              double d;
              d = i;                 // 正確, 不需要進行類型轉換,d=3.0
              
              d = (double) i;        // 也可以使用顯示類型轉換
              double aDouble = 55;   // 編譯器會自動的將int 55轉換成double 55.0
              double nought = 0;     // 編譯器會自動的將int 0轉換成double 0.0
                          // 值得注意的是int 0和double 0.0是不同的

              下面的這幅圖展示了編譯器隱示類型轉換的順序,轉換規則是將小類型晉升為大類型,這樣做可以防止精度缺失。降級類型需要顯示類型轉換,精度會缺失,值得注意的是char會被視作16位無符號整數,取值范圍[0, 65535],boolean類型不支持轉換。

              隱式轉換

              例子,計算從1到100的平均值,仔細研究下面的代碼

              public class Sum1To100 {
                 public static void main(String[] args) {
                    int sum = 0;
                    double average;
                    int number = 1;
                    while (number <= 100) {
                       sum += number;      // sum最後的結果為int 5050
                       ++number;
                    }
                    average = sum / 100;   // average = 50.0而不是50.5
                    System.out.println("Average is " + average);  // 平均值為50.0
                 }
              }

              這是因為sum與100都是int類型,二者相除返回的是被截斷的int,如果想得到正確的結果,你可以采用下面的方式:

              average = (double)sum / 100;     // 進行除法運算前顯示的將sum轉成double類型
              average = sum / (double)100;     // 進行除法運算前顯示的將100轉成double類型
              average = sum / 100.0;
              average = (double)(sum / 100);   // 這種做法是錯誤的,你知道是什麼原因嗎?

              6. 復合賦值運算

              除了前面介紹的常用的賦值運算=,Java還提供了其它的復合賦值運算:

              操作符 解釋 使用 例子 = 賦值
              將右操作數賦值給左操作數 var=expr x = 5; +=

              復合加法運算

              var+=expr
              等價於var=var+expr x += 5;
              等價於x = x + 5 -= 復合減法運算 var-=expr
              等價於var=var-expr x -= 5;
              等價於x = x - 5 *= 復合乘法運算 var*=expr
              等價於var=var*expr x *= 5;
              等價於x = x * 5 /= 復合除法運算 var/=expr
              等價於var=var/expr x /= 5;
              等價於x = x / 5 %= 復合取余運算 var%=expr
              等價於var=var%expr x %= 5;
              等價於x = x % 5

              7. 自增/自減

              對於一元運算自增(++)和自減(--),適用於除boolean類型以外的其它 基本類型byte, short, char, int, long, float和double。

              操作符 解釋 例子 ++ 原數值加1
              x++或++x等價於x += 1或x = x + 1 int x = 5;
              x++;
              ++x; -- 原數值減1
              x--或--x等價於x -= 1或x = x - 1 int y = 6;
              y--;
              --y;

              自增和自減都是基於自身的操作,例如x++自增後重新返回給x。
              自增/自減操作符號可以放置於操作數之前,也可以放在操作數之後,但是兩者有著不同的意義。

              如果這些運算符基於自身操作,運算符前置和後置具有同樣的效果,例如++x和x++,因為表達式的值會被忽略。
              如果用於其它的操作,例如y=x++或y=++x,對於y值來說運算符前置和後置有不同的值。

              操作符 解釋 例子 ++var 自增
              首先var加1,計算結果使用var y = ++x;
              等價於x=x+1; y=x; var++ 自增
              首先計算結果使用var,接著var加1 y = x++;
              等價於oldX=x; x=x+1; y=oldX; --var 自減 y = --x;
              等價於x=x-1; y=x; var-- 自減 y = x--;
              等價於oldX=x; x=x-1; y=oldX;

              8. 關系和邏輯運算符

              很多時候,你需要對兩個值進行比較之後,才會進行某些操作,舉例如果mark值大於等於50,輸出"PASS!"。
              Java提供了6種比較運算符,經過比較運算後返回布爾值即true或false。

              操作符 解釋 使用 例子(x=5, y=8) == 相等 expr1==expr2 (x == y) → false != 不相等 expr1!=expr2 (x != y) → true > 大於 expr1>expr2 (x > y) → false >= 大於等於 expr1>=expr2 (x >= 5) → true < 小於 expr1 (y < 8) → false <= 小於等於 expr1>=expr2 (y <= 8) → true

              每個比較運算符需要兩個操作數,正確的寫法:x > 1 && x < 100,錯誤的寫法 1 < x < 100, 這裡面&&表示與操作。
              Java提供了4種基於boolean的邏輯運算,按照優先級順序如下:

              操作符 解釋 使用 ! 邏輯非 !booleanExpr ^ 邏輯異或 booleanExpr1^booleanExpr2 && 邏輯與 booleanExpr1&&booleanExpr2 || 邏輯或 booleanExpr1||booleanExpr2

              真值表如下:

              與(&&) true false true true false false false false       或(||) true false true true true false true false       非(!) true false Result false true       異或(^) true false true false true false true false

              舉例說明:

              // 如果x取值范圍在[0,100],返回true
              (x >= 0) && (x <= 100)
              
              // 如果x取值范圍不在[0,100],返回true
              (x < 0) || (x > 100)
              !((x >= 0) && (x <= 100))
              
              // 計算是否為閏年:某年被4但不能被100整除,或者被400整除
              ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)

              練習:研究下面的程序並解釋輸出。

              public class RelationalLogicalOpTest {
                 public static void main(String[] args) {
                    int age = 18;
                    double weight = 71.23;
                    int height = 191;
                    boolean married = false;
                    boolean attached = false;
                    char gender = 'm';
              
                    System.out.println(!married && !attached && (gender == 'm'));
                    System.out.println(married && (gender == 'f'));
                    System.out.println((height >= 180) && (weight >= 65) && (weight <= 80));
                    System.out.println((height >= 180) || (weight >= 90));
                 }
              }
              練習:

              根據提供的日期:年、月(1-12)和日(1-31),計算該日期是否早於1582年10月15日。

              運算符優先級

              優先級由高到低:'!','^','&&','||',編程中如果不確定,請使用括號()。

              System.out.println(true || true && false);    // true (和下面的一樣)
              System.out.println(true || (true && false));  // true
              System.out.println((true || true) && false);  // false
              
              System.out.println(false && true ^ true);     // false (和下面的一樣)
              System.out.println(false && (true ^ true));   // false
              System.out.println((false && true) ^ true);   // true
              短路操作符

              邏輯與(&&)和邏輯或(||)被稱為短路操作符,這意味計算結果如果可以通過左操作數來確定,那麼右操作數會被忽略,例如false && ...會返回false,true || ...會返回true。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved