Char、float、Double、BigDecimal
Char初識
char:
- char類型是一個單一的 16 位 Unicode 字符
- char 在java中是2個字節(“字節”是byte,“位”是bit ,1 byte = 8 bit )
- 最小值是 \u0000(即為0)
- 最大值是 \uffff(即為65,535)
- char 數據類型可以儲存任何字符
- 例子:char letter = ‘A‘
char是Java中的保留字,與別的語言不同的是,char在Java中是16位的,因為Java用的是Unicode。不過8位的ASCII碼包含在Unicode中,是從0~127的。
Java中使用Unicode的原因是,Java的Applet允許全世界範圍內運行,那它就需要一種可以表述人類所有語言的字符編碼。Unicode。但是English,Spanish,German, French根本不需要這麽表示,所以它們其實采用ASCII碼會更高效。這中間就存在一個權衡問題。
因為char是16位的,采取的Unicode的編碼方式,所以char就有以下的初始化方式:
char c=‘c‘; //字符,可以是漢字,因為是Unicode編碼
char c=十進制數,八進制數,十六進制數等等; //可以用整數賦值
char c=‘\u數字‘; //用字符的編碼值來初始化,如:char=‘\0‘,表示結束符,它的ascll碼是0, 這句話的意思和 char c=0 是一個意思。
Char和String的轉換
String轉換為char
- 使用String.charAt(index)(返回值為char)可以得到String中某一指定位置的char。
- 使用String.toCharArray()(返回值為char[])可以得到將包含整個String的char數組。這樣我們就能夠使用從0開始的位置索引來訪問string中的任意位置的元素。
char轉換為String
將char轉換為String大致有6種方法。總結如下:
1. String s = String.valueOf(‘c‘); //效率最高的方法 2. String s = String.valueOf(new char[]{‘c‘}); //將一個char數組轉換成String 3. String s = Character.toString(‘c‘); // Character.toString(char)方法實際上直接返回String.valueOf(char) 4. String s = new Character(‘c‘).toString(); 5. String s = "" + ‘c‘; // 雖然這個方法很簡單,但這是效率最低的方法 // Java中的String Object的值實際上是不可變的,是一個final的變量。 // 所以我們每次對String做出任何改變,都是初始化了一個全新的String Object並將原來的變量指向了這個新String。 // 而Java對使用+運算符處理String相加進行了方法重載。 // 字符串直接相加連接實際上調用了如下方法: // new StringBuilder().append("").append(‘c‘).toString(); 6. String s = new String(new char[]{‘c‘});
Java中,Float和Double數據額類型的地位
一直疑惑,Float和Double既然有丟失精度的潛力,為什麽java還留著
Float : 單精度浮點數
Double : 雙精度浮點數
兩者的主要區別如下:
01.在內存中占有的字節數不同
單精度浮點數在機內存占4個字節
雙精度浮點數在機內存占8個字節
02.有效數字位數不同
單精度浮點數有效數字8位
雙精度浮點數有效數字16位
03.數值取值範圍
單精度浮點數的表示範圍:-3.40E+38~3.40E+38
雙精度浮點數的表示範圍:-1.79E+308~-1.79E+308
04.在程序中處理速度不同
一般來說,CPU處理單精度浮點數的速度比處理雙精度浮點數快
如果不聲明,默認小數為double類型,所以如果要用float的話,必須進行強轉
例如:float a=1.3; 會編譯報錯,正確的寫法 float a = (float)1.3;或者float a = 1.3f;(f或F都可以不區分大小寫)
註意:float是8位有效數字,第7位數字將會四舍五入
面試題:
1.java中3*0.1==0.3將會返回什麽?true還是false?
fale,因為浮點數不能完全精確的表示出來,一般會損失精度。
2.java中float f = 3.4;是否正確?
不正確,3.4是雙精度數,將雙精度型(double)賦值給浮點型(float)屬於向下轉型會造 成精度損失,因此需要強制類型轉換float f = (float)3.4;或者寫成 float f = 3.4f;才可以。
在《Effective Java》這本書中也提到這個原則: Float和Double只能用來做科學計算或者是工程計算; 在商業計算中我們要用java.math.BigDecimal
BigDecimal構造方法
- public BigDecimal(double val) 將double表示形式轉換為BigDecimal *不建議使用
- public BigDecimal(int val) 將int表示形式轉換成BigDecimal
- public BigDecimal(String val) 將String表示形式轉換成BigDecimal
為什麽不建議采用第一種構造方法呢?來看例子
public static void main(String[] args){
BigDecimal bigDecimal = new BigDecimal(2);
BigDecimal bDouble = new BigDecimal(2.3);
BigDecimal bString = new BigDecimal("2.3");
System.out.println("bigDecimal=" + bigDecimal);
System.out.println("bDouble=" + bDouble);
System.out.println("bString=" + bString);
}
/**
輸出:bigDecimal=2
bDouble=2.299999999999999
bString==2.3
*/
/**
為什麽會出現這種情況呢?
JDK的描述:
1、參數類型為double的構造方法的結果有一定的不可預知性。有人可能認為在Java中寫入newBigDecimal(0.1)所創建的BigDecimal正好等於 0.1(非標度值 1,其標度為 1),但是它實際上等於0.1000000000000000055511151231257827021181583404541015625。這是因為0.1無法準確地表示為 double(或者說對於該情況,不能表示為任何有限長度的二進制小數)。這樣,傳入到構造方法的值不會正好等於 0.1(雖然表面上等於該值)。
2、另一方面,String 構造方法是完全可預知的:寫入 newBigDecimal("0.1") 將創建一個 BigDecimal,它正好等於預期的 0.1。因此,比較而言,通常建議優先使用String構造方法。
*/
通常建議BigDecimal優先使用String構造方法
Char、float、Double、BigDecimal