計算機科學起源於數學,早期的計算機也確實多用於數學運算,以致於後來的各路編程語言,仍然保留着古老的加減乘除四則運算。這四則運算在Java語言中有專門的運算符加以表示,像加法符號「+」對應Java的「+」,減法符號「-」對應Java的「-」,乘法符號「×」對應Java的「*」,除法符號「÷」對應Java的「/」,除此以外,還有一個求餘數運算,在數學上使用mod表示,而Java對應的求餘運算符爲「%」。四則運算加求餘數運算構成了Java編程的基礎算術,數字和運算符的書寫順序與大衆寫法並沒有差別,下面即是這幾種基本運算的代碼例子:java
int sum = 1+2; // 求兩數相加之和 System.out.println("sum="+sum); int differ = 7-3; // 求兩數相減之差 System.out.println("differ="+differ); int product = 5*6; // 求兩數相乘之積 System.out.println("product="+product); int quotient = 81/9; // 求兩數相除之商 System.out.println("quotient="+quotient); int remainder = 40%3; // 求兩數相除之餘數 System.out.println("remainder="+remainder);
運行以上測試代碼,獲得以下的運算日誌。編程
sum=3 differ=4 product=30 quotient=9 remainder=1
可見上述的運算結果符合日常的加減乘除邏輯。編程語言
整數的四則運算看來是波瀾不驚,假若有小數參與運算,計算結果仍是同樣的嗎?接下來先看個除法運算,前面的除法算的是81除以9,由於恰好能除盡,因此求得的商毫無疑義是9。那末換種除不盡的狀況,好比說25除以4,按平常生活中的除法,此時求得的商應該是6.25。可是Java語言另有規定,若是被除數和除數都是整型,求得的商也只能是整型數,故而25除以4獲得的商變成了6,也就是省略了小數部分。要想讓這個商成爲包括小數部分的數值,就必須讓被除數和除數之一變成小數,只有其中一個是小數,Java纔會把整數的除法運算轉爲小數的除法運算。例如25.0/四、25/4.0、25.0/4.0這幾種寫法,都將變成雙精度類型的除法,最後求得的商也變做了雙精度數6.25。下面是前述的除法運算用到的實驗代碼:測試
// 被除數和除數都是整數,則求得的商爲去掉小數部分的整數 int quotientInt = 25/4; System.out.println("quotientInt="+quotientInt); // 被除數和除數只要有一個是浮點或雙精度數,則求得的商保留小數部分 double quotientDouble = 25.0/4; // 25/4.0的運算結果跟25.0/4是同樣的 //double quotientDouble = 25/4.0; System.out.println("quotientDouble="+quotientDouble);
運行上面的實驗代碼,打印出來的運算日誌見下。日誌
quotientInt=6 quotientDouble=6.25
然而對小數進行除法運算,有時候計算結果並不精確,譬如如下的測試代碼:blog
// 由於float和double類型自身爲約數表示,因此除法運算獲得的商也是約數,不能保證小數部分是精確的 double quotientDecimal = 8.1/3; System.out.println("quotientDecimal="+quotientDecimal); // 對浮點數和雙精度數求餘數,也存在約數形成的問題,即餘數的小數部分可能並不許確 double remainderDecimal = 5.1%2; System.out.println("remainderDecimal="+remainderDecimal);
這個測試代碼的運算很簡單,8.1除以3正常求得的商爲2.7,至於5.1除以2的餘數正常應爲1.1。但是一旦運行上述的測試代碼,會發現除法結果居然是下面這樣的:ci
quotientDecimal=2.6999999999999997 remainderDecimal=1.0999999999999996
以上獲得的商和餘數真是叫人目瞪口呆,說好的2.7和1.1怎麼走樣了呢?其實這種狀況在一開始便埋下伏筆了,以前介紹浮點型和雙精度型時,提到它們自己並不是精準的數值,而是一個尾數乘以10的若干次方,而且浮點型的精度只有6到7位,雙精度型的精度則爲15-16位,精度之外的數字純屬打醬油的。如今Java對小數進行除法運算,打醬油部分的數字也來湊熱鬧,原本能除得盡的小數,因爲些許的誤差反而變得除不盡了,以致形成多此一舉的尷尬。這就告訴咱們,要謹慎對待小數的除法和取餘數運算。rem