官术网_书友最值得收藏!

2.1.3 強制類型轉換

在編碼過程中,不但能將數字賦值給某個變量,還能將一個變量賦值給另一個變量。比如下面的代碼把整型變量changjiang賦值給整型變量longRiver(完整代碼見本章源碼的src\com\arithmetic\ numerical\Convert.java):

        int changjiang=6397;  // 長江的長度為6397千米
        System.out.println("changjiang="+changjiang);
        int longRiver=changjiang;  // 把一個整型變量賦值給另一個整型變量
        System.out.println("longRiver="+longRiver);

運行上面的測試代碼,從下面的輸出日志可以發現兩個整型變量的數值一模一樣。

changjiang=6397

longRiver=6397

同類型的變量之間互相賦值完全沒有問題,麻煩的是給不同類型的變量賦值。如果是把整型變量賦值給長整型變量,編譯器睜一只眼閉一只眼就給放行了;如果是把長整型變量賦值給整型變量, IDEA就會直接提示錯誤Incompatible types。比如以下代碼就會報錯:

        long changjiang=6397;  // 長江的長度為6397千米
        // 若把長整型變量直接賦值給整型變量,編譯器會提示錯誤
        int longRiver=changjiang;  // 把長整型變量賦值給整型變量,注意編譯器會報錯

此時需要在原變量前面添加“(新類型)”表示強制將該變量轉換為新類型。改寫后的變量賦值語句就變成了下面這樣:

        long changjiang=6397;  // 長江的長度為6397千米
        // 不同類型的變量相互賦值,需要在原變量前面添加“(新類型)”表示強制轉換類型
        int longRiver=(int) changjiang;  // 把長整型數強制轉換成整型數

然而,不同類型的變量相互賦值是有風險的,尤其是把高精度的數字賦值給低精度的數字,例如將8字節的長整型數強制轉換成4字節的整型數,結果只有低位的4字節保留了下來,而高位的4字節被舍棄掉了。下面做一個實驗,先用長整型變量保存世界人口的數量74億,再把該長整型變量賦值給整型變量,具體代碼如下:

        long worldPopulation=7444443881L; //截至2018年元旦,世界人口大約有74億
        System.out.println("worldPopulation="+worldPopulation);
        // 把長整型數賦值給整型數會丟失前4字節
        int shijierenkou=(int) worldPopulation;  // 把長整型數強制轉換成整型數
        System.out.println("shijierenkou="+shijierenkou);

運行以上的實驗代碼,打印出來的變量值見以下日志:

worldPopulation=7444443881

shijierenkou=-1145490711

可見將超大的長整型數強制轉換成整型數,結果整個數值都變了。

既然整數之間強制轉換類型存在問題,小數之間強制轉換類型也不例外。倘若把雙精度數強制轉換成浮點數,數字精度也會變差。接下來,仍然通過實驗觀察,以常見的圓周率為例,它的密率是中國古代數學家祖沖之發現的,其數值約為3.1415926,包括小數部分在內共有8位數字。由于double類型的數字精度達到15~16位,因此利用雙精度變量保存圓周密率完全沒有問題。但是如果將這個密率的雙精度變量賦值給浮點變量,會發生什么情況呢?下面的代碼將演示把雙精度數強制轉換成浮點數的場景:

        // 3.1415926是中國古代數學家祖沖之求得的圓周率數值,又稱祖率
        double zulv=3.1415926;
        System.out.println("zulv="+zulv);
        // 把雙精度數賦值給浮點數會丟失數值精度
        float pai=(float) zulv;  // 把雙精度數強制轉換成浮點數
        System.out.println("pai="+pai);

運行上述實驗代碼,日志打印的變量值如下:

zulv=3.1415926

pai=3.1415925

可見浮點變量保存的密率數值變成了3.1415925,與雙精度變量相比,末尾的6變為5了。之所以密率數值發生變化,是因為float類型的數字精度只有6~7位,而前述密率的總位數達到8位,顯然超出了float類型的精度范圍,使得強轉之后的浮點變量損失了范圍外的精度。

除了整數之間互轉、小數之間互轉以外,還有整數轉小數和小數轉整數的情況,不過整數與小數互轉依然存在數值虧損的問題。譬如,一個雙精度變量賦值給一個整型變量,由于整型變量沒有空間保存小數部分,因此原本雙精度變量在小數點后面的數字全被舍棄。以下代碼將示范這種數字類型轉換:

        double jiage=9.9;  // 某商品定價為9.9元
        System.out.println("jiage="+jiage);
        // 把小數賦值給整型變量,會直接去掉小數點后面的部分,不會四舍五入
        int price=(int) jiage;  // 把雙精度數強制轉換成整型數
        System.out.println("price="+price);

運行以上的測試代碼,日志打印結果如下:

jiage=9.9

price=9

果然整型變量丟掉了雙精度變量的小數部分。由此可見,不同類型之間的變量互轉問題多多,若非必要,一般不要強制轉換兩個變量的數值類型。

主站蜘蛛池模板: 家居| 双城市| 宁国市| 深泽县| 无棣县| 宁南县| 浑源县| 信丰县| 洛扎县| 辽宁省| 巴中市| 玉溪市| 皋兰县| 加查县| 屏山县| 民权县| 桂阳县| 永修县| 和田县| 屏东县| 昭通市| 中江县| 电白县| 革吉县| 黎平县| 七台河市| 丰城市| 桂平市| 铜鼓县| 太原市| 安溪县| 资讯 | 塘沽区| 尉氏县| 伊通| 大石桥市| 兰州市| 通化县| 乡城县| 满城县| 南昌县|