1. 程式人生 > 其它 >java浮點數儲存

java浮點數儲存

技術標籤:javajava補碼程式語言

面試題:

public class FloatDouble {
 
	public static void main(String[] args) {
 
		float f_v1 = 20;  
		float f_v2 = 20.3f;  
		float f_v3 = 20.5f;  
		      
		double d_v1 = 20;  
		double d_v2 = 20.3;  
		double d_v3 = 20.5;
		
		System.out.println((f_v1 == d_v1)?"true":"false"
); System.out.println(f_v2 == d_v2?"true":"false"); System.out.println(f_v3 == d_v3?"true":"false"); } }

執行結果會是怎樣的呢?, 解釋執行結果的原因

這裡涉及到浮點數是如何儲存的.

  1. 如何將十進位制轉換成二進位制浮點數呢, 先介紹一下十進位制的浮點數 轉換二進位制的浮點數

分為兩部分:

  1. 先將整數部分轉換為二進位制,

  2. 將小數部分轉換為二進位制, 然後將整數部分與小數部分相加。

以 20.5 轉換為例,

20轉換後變為 10100
0.5 要轉換二進位制,需要乘2, 乘完之後取整數部分,然後用乘的結果減去整數部分, 然後接著乘2, 直至最後沒有小數或者小數出現迴圈, 即乘完.

如果等於0, 就取前面不為0的部分.

0.5 * 2 = 1.0 (取1)

0 * 2 = 0 (0)

所以, 轉換後 0.5 = 0.1,

所以 20.5 轉換二進位制後, 20.5 = 10100.1(二進位制)


再看一個浮點數 20.3

20 = 10100 (二進位制)

0.3 * 2= 0.6 (0)

0.6 * 2 = 1.2 (1)

0.2 * 2= 0.4 (0)

0.4 * 2 = 0.8 (0)

0.8 *2 = 1.6 (1)

計算到這裡, 將再出現0.6,進入迴圈了,所以,結果

0.3 = 0.010011001…1001

所以20.3 = 10100.010011001…1001 (二進位制).

2.如果要把十進位制浮點數,儲存到記憶體空間中,也就是4個位元組中,首先要把浮點數轉換成二進位制的浮點數, 然後再轉換成科學計數法.

這裡 20.5 = 10100.1(二進位制) = 1.01001E4(十進位制科學計數) = 1.01001E100(二進位制科學計數), 這裡E100指2的100次方

在java中,float 型別 數,佔4個位元組, 儲存結構如下

             符號位:   1

             指數位:   8

             尾數位:   23,  如下圖所示

           double 型別數,  佔8個位元組, 儲存結構如下

             符號位:1

             指數位:11

             尾數位: 52

儲存資料是一個蘿蔔一個坑, 首先儲存符號位, 然後是 指數,最後尾數

比如20.5 = 1.01001E100(二進位制)

這裡使用到移位儲存, 對於float 數值來說, 指數位要加上127, 即0111111(二進位制)

00000100

+01111111


1000 0011

對於double 數值來說, 指數位要加上1023, 即0111 111 1111(二進位制)

0000 000 0100

  • 0111 111 1111

1000 000 0011

所以20.5 儲存的數值 是 (float): 0-10000011-01001 00000 00000 00000 000

(double):0-10000000011-01001+(47個0)
這裡尾數位需要52位

現在看到20.5 轉換為float, double 的二進位制數, 指數和尾數是不同的, 注意,比較指數時 float 型會-127, double型 會-1023,因此

float 型又變成了00000100

double型又變成0000000100 ,這時候比較,因為兩個指數的位數不同,一個8位,一個10位,8位的數會在前面自動補0

比較尾數時,float型數會自動在後面補0直至與double 型相同的52位

同理20.3 儲存的數值 是: (float) 0-10000011-01001 10010 10011 00101 001

(double)0-1000000011-01001(後面迴圈1001, 直至尾數為52位)

與20.5的比較相似, 20.3的float型二進位制和double型二進位制,符號位與指數位都相同, 但是尾數位不相同,float型到了23位之後都是0, double型一直1001迴圈到52位. 這就是float型與double型比較之後不相等的原因
在這裡插入圖片描述
如果要將三個比較結果 都為true, 需在d_v2加上 (float), 也就是將double強制轉為float型