天天看點

Java:有關資料方面的一些小知識 

問題一:

byte b1 = 3,b2  = 4,b;
b = b1+b2;
b = 3+4;
           

哪一句是編譯失敗的?為什麼?

答案:

b = b1+b2;是有問題的。

因為變量相加,會首先看類型的問題,當最終把結果指派時也會考慮類型的問題。(short和byte類型運算結果會自動轉換為int型,系統會擔心損失精度,是以會報錯,不讓運作!)

但是當常量相加時,會首先做加法,然後看結果是否在指派的資料類型範圍内,如果不在才會報錯。

代碼驗證:

Java:有關資料方面的一些小知識 

我們可以很明顯的看到類型不對!

Java:有關資料方面的一些小知識 
Java:有關資料方面的一些小知識 

程式正常的運作出來了!

其實這個問題涉及到了一個知識點——變量相加和常量相加的差別!

對于其他資料類型的使用也是類似的!

問題二:

System.out.println("hello" + 'a' + 1);
System.out.println('a' + 1 + "hello");
           

這兩句有差別嗎?

答案:

有很大的差別!

當字元串和其他資料做+時,結果是字元串類型,這裡的+不是加法運算,而是字元串連接配接符。

但是當多個其他資料和字元串做+時,會先讓前面的資料進行加法運算,再和字元串進行連接配接操作。

(說到底就是順序的問題!)

代碼驗證:

Java:有關資料方面的一些小知識 
Java:有關資料方面的一些小知識 

問題三:

short s = 1;s = s+1;
short s = 1;s+=1;
           

上面的兩行代碼有沒有問題?如果有問題在哪? 

答案:

第一個有問題,第二個沒有問題!

第一行代碼在于s+1運算之後得到的資料是int型,是以類型不相容,系統會擔心損失精度,是以會報錯,不讓運作!(其實和問題一的問題有點類似!)

第二行代碼關鍵在于,擴充的指派運算符實際上隐含了一個強制類型轉換。

s += 1不是等價于s = s + 1;而是等價于s = (s的資料類型)(s+1);

代碼驗證:

Java:有關資料方面的一些小知識 

我們可以很明顯的看到類型不對!

Java:有關資料方面的一些小知識 

 當換回s+=1的時候,程式并沒有報錯,可以正常的運作!

可以推廣到其他的資料類型和運算符:

Java:有關資料方面的一些小知識 

問題四:

資料類型預設轉換的時候:

byte、short、char—int—long—float—double

但是我們知道long占8個位元組,float占4個位元組。

你就不會感到疑惑嗎?四個位元組的float怎麼裝得下八個位元組的long,資料不會溢出嗎?那是怎麼實作的呢?

答案:

首先float類型資料是裝得下long類型資料的:

float資料範圍:

  • 負數範圍:-3.4×1038~-1.4×10-45
  • 正數範圍:1.4×10-45~3.4×1038

long資料範圍:

  • -263~263-1

3.4x10^38 > 2x10^38 > 2x8^38 = 2x2^3^38 > 2x2^114 >2^63-1

是以float類型是完全裝得下long類型資料的。

那麼為什麼裝得下呢?

關鍵就在于底層實作的方式不同。

簡單解釋:

long類型就類似于00000000 00000000 00000000... ...直接存!

float類型類似于數學裡面的科學記數法

是以float類型資料存儲資料的範圍大。

補充:

float的具體存儲方式:

float類型數字在計算機中用4個位元組存儲。遵循IEEE-754格式标準:

一個浮點數有2部分組成:底數m和指數e

底數部分 使用二進制數來表示此浮點數的實際值

指數部分 占用8bit的二進制數,可表示數值範圍為0-255

但是指數可正可負,是以,IEEE規定,此處算出的次方必須減去127才是真正的指數。

是以,float類型的指數可從-126到128

底數部分實際是占用24bit的一個值,但是最高位始終為1,是以,最高位省去不存儲,在存儲中占23bit

科學計數法。

格式:

SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

S表示浮點數正負    

E指數加上127後的值得二進制資料

M底數

舉例:

17.625在記憶體中的存儲

首先要把17.625換算成二進制:10001.101

整數部分,除以2,直到商為0,餘數反轉。

小數部分,乘以2,直到乘位0,進位順序取。

在将10001.101右移,直到小數點前隻剩1位:

1.0001101 * 2^4 因為右移動了四位

這個時候,我們的底數和指數就出來了

底數:因為小數點前必為1,是以IEEE規定隻記錄小數點後的就好。是以,此處的底數為:0001101

指數:實際為4,必須加上127(轉出的時候,減去127),是以為131。也就是10000011

符号部分是整數,是以是0

綜上所述,17.625在記憶體中的存儲格式是:

01000001 10001101 00000000 00000000

Ending... ...