float和double有什麼區別?

float和double在遊戲行業確定是用的不少的,雖然這是個很基礎的問題,可是面試時被問到仍是感受說的不是很好。
因此仍是總結一下:面試

float 單精度浮點數在機內佔 4 個字節,用 32 位二進制描述。編程

double 雙精度浮點數在機內佔 8 個字節,用 64 位二進制描述。編程語言

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

數符佔 1 位二進制,表示數的正負。.net

指數符佔 1 位二進制,表示指數的正負。翻譯

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

指數存指數的有效數字。htm

指數佔多少位,尾數佔多少位,由計算機系統決定。blog

多是數符加尾數佔 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"也能夠不寫

  1. 特別須要注意的是兩個浮點數的算術運算

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

 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,它的小數點移動到了一個新的位置(即浮動了)。可見,浮點數原本就是用於科學計算的,用來進行精確計算實在太不合適了。

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

相關文章
相關標籤/搜索