float和double有什麼區別?

float和double在遊戲行業肯定是用的很多的,雖然這是個很基礎的問題,但是面試時被問到還是感覺說的不是很好。
所以還是總結一下:

float 單精度浮點數在機內占 4 個位元組,用 32 位二進位描述。

double 雙精度浮點數在機內占 8 個位元組,用 64 位二進位描述。

浮點數在機內用指數型式表示,分解為:數符,尾數,指數符,指數四部分。

數符占 1 位二進位,表示數的正負。

指數符占 1 位二進位,表示指數的正負。

尾數表示浮點數有效數字,0.xxxxxxx, 但不存開頭的 0 和點。

指數存指數的有效數字。

指數佔多少位,尾數佔多少位,由電腦系統決定。

可能是數符加尾數占 24 位,指數符加指數占 8 位 — float。

數符加尾數占 48 位,指數符加指數占 16 位 — double。

知道了這四部分的佔位,按二進位估計大小範圍,再換算為十進位,就是你想知道的數值範圍。

對編程人員來說,double 和 float 的區別是 double 精度高,有效數字 16 位,float 精度 7 位。但 double 消耗記憶體是 float 的兩倍,double 的運算速度比 float 慢得多,
C 語言中數學函數名稱 double 和 float 不同,不要寫錯,能用單精度時不要用雙精度(以省記憶體,加快運算速度)。

簡單來說,Float 為單精度,記憶體中占 4 個位元組,有效數位是 7 位(因為有正負,所以不是8位),在我的電腦且 VC++6.0 平台中默認顯示是6位有效數字;double為 雙精度,占 8 個位元組,有效數位是 16 位,但在我的電腦且 VC++6.0 平台中默認顯示同樣是 6 位有效數字

例子:在 C 和 C++ 中,如下賦值語句:

float a=0.1; 

編譯器報錯:warning C4305: ‘initializing’ : truncation from ‘const double ‘ to ‘float ‘

原因: 在 C/C++ 中(也不知道是不是就在 VC++ 中這樣),上述語句等號右邊 0.1,我們以為它是個 float,但是編譯器卻把它認為是個 double(因為小數默認是 double),所以要報這個 warning,一般改成 0.1f 就沒事了。

本人通常的做法,經常使用 double,而不喜歡使用 float。

C 語言和 C# 語言中,對於浮點類型的數據採用單精度類型 float 和雙精度類型 double 來存儲,float 數據佔用 32bit, double 數據佔用 64bit,我們在聲明一個變數 float f= 2.25f 的時候,是如何分配記憶體的呢?如果胡亂分配,那世界豈不是亂套了么,其實不論是 float 還是 double 在存儲方式上都是遵從 IEEE 的規範 的,float 遵從的是 IEEE R32.24 ,而 double 遵從的是 R64.53。

無論是單精度還是雙精度在存儲中都分為三個部分:

符號位(Sign):0 代表正,1 代表為負。
指數位(Exponent):用於存儲科學計數法中的指數數據,並且採用移位存儲。
尾數部分(Mantissa):尾數部分。

特別注意:

當你不聲明的時候,默認小數都用double來表示,所以如果要用float的話,則應該在其後加上f

例如:float a=1.3;

則會提示不能將double轉化成float 這成為窄型轉化

如果要用float來修飾的話,則應該使用float a=1.3f

注意float是8位有效數字,第7位數字將會產生四捨五入

所以如果一個float變數 這樣定義: float a=1.32344435; 則第7位將產生四捨五入(5及5以下的都將捨去)

1.兩個在定義時的區別

(1)float型 記憶體分配4個位元組,佔32位,範圍從10-38到1038 和 -1038到-10-38

例float x=123.456f,y=2e20f; 注意float型定義的數據末尾必須有”f”或”F”,為了和double區別

(2)double型 記憶體分配8個位元組,範圍從10-308到10308 和 -10-308到-10-308
例:double x=1234567.98,y=8980.09d; 末尾可以有”d”也可以不寫

2、特別需要注意的是兩個浮點數的算術運算

直接使用 +,-,*,%運算符的問題

 public class Test{
        public static void main(String args[]){
        System.out.println(0.05+0.01);
        System.out.println(1.0-0.42);
        System.out.println(4.015*100);
        System.out.println(123.3/100);
        }
    }

結果:

0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999

原因:

首先得從電腦本身去討論這個問題。我們知道,電腦並不能識別除了二進位數據以外的任何數據。無論我們使用何種程式語言,在何種編譯環境下工作,都要先把源程式翻譯成二進位的機器碼後才能被電腦識別。
以上面提到的情況為例,我們源程式里的2.4是十進位的,電腦不能直接識別,要先編譯成二進位。但問題來了,2.4的二進位表示並非是精確的2.4,反而最為接近的二進位表示是2.3999999999999999。原因在於
浮點數由兩部分組成:指數和尾數,這點如果知道怎樣進行浮點數的二進位與十進位轉換,應該是不難理解的。如果在這個轉換的過程中,浮點數參與了計算,那麼轉換的過程就會變得不可預知,並且變得不可逆。
我們有理由相信,就是在這個過程中,發生了精度的丟失。而至於為什麼有些浮點計算會得到準確的結果,應該也是碰巧那個計算的二進位與十進位之間能夠準確轉換。而當輸出單個浮點型數據的時候,可以正確輸出,如

double d = 2.4;
System.out.println(d);

輸出的是2.4,而不是2.3999999999999999。也就是說,不進行浮點計算的時候,在十進位里浮點數能正確顯示。
這更印證了我以上的想法,即如果浮點數參與了計算,那麼浮點數二進位與十進位間的轉換過程就會變得不可預知,並且變得不可逆。

事實上,浮點數並不適合用於精確計算,而適合進行科學計算。這裡有一個小知識:既然float和double型用來表示帶有小數點的數,那為什麼我們不稱它們為「小數」或者「實數」,要叫浮點數呢?因為這些數都以科學計數法的形式存儲。
當一個數如50.534,轉換成科學計數法的形式為5.053e1,它的小數點移動到了一個新的位置(即浮動了)。可見,浮點數本來就是用於科學計算的,用來進行精確計算實在太不合適了。

參考:
//my.oschina.net/zd370982/blog/724265
//www.jb51.net/article/159043.htm