float和double有什麼區別?

2021-02-19 Java資料站

點擊上方藍色字體,選擇「標星公眾號」

優質文章,第一時間送達

  作者 |  kelexin

來源 |  urlify.cn/ZnueQr

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

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

粉絲福利:Java從入門到入土學習路線圖

👇👇👇

感謝點讚支持下哈 

相關焦點

  • MySQL資料庫中float、double、decimal三個浮點類型到底有什麼區別?
    的值                                               | 依賴於M和D的值                                               | 小數值          |那麼MySQL中這三種都是浮點類型 它們彼此的區別又是什麼呢 ??
  • 詳解C語言數據類型:float與double
    這種論點提升到底是什麼?當較小尺寸的參數(特別是char,short和float)傳遞給可變參數函數(如printf之類的函數,其參數數量不固定)時,它們將轉換為較大尺寸。Char和short轉換為int,float轉換為double。為什麼這樣 據我所知,純粹出於歷史原因。
  • C要點5:float、double、long double(大小,範圍,輸入輸出符,科學計數法)
    浮點型:數學裡的小數C語言浮點型有三個類型:float、double、long double輸入輸出輸出格式符: 默認輸出
  • 變量專題之二:double,float和浮點變量底層表示
    小數在程序界被稱為浮點數 (Floating-point arithmetic),這個名稱的由來和浮點數在計算機底層中的存在方式有關。Java中,有兩種變量可以儲存小數類型double 和 float當我們需要表示一個浮點數 (小數) 時,大部分情況下創建一個 double(雙精度浮點數) 類型的變量即可。
  • java類型轉換String互轉int,double, float, BigDecimal
    >String 轉 int ,double, float, BigDecimalString轉intString str = "123";int a = Integer.parseInt(str);int轉String第一種方法:s=i+"";第二種方法:s=String.valueOf(i);String轉float
  • java float double精度為什麼會丟失?淺談java的浮點數精度問題
    20014999 這麼小的數字在float下沒辦法表示。於是帶著這個問 題,做了一次關於float和double學習,做個簡單分享,希望有助於大家對java 浮 點數的理解。 關於 java 的 float 和 doubleJava 語言支持兩種基本的浮點類型: float 和 double 。
  • c語言基本數據類型short、int、long、char、float、double
    double 這六個關鍵字代表C 語言裡的六種基本數據類型。現在我們聯想一下,short、int、long、char、float、double 這六個東東是不是很像不同類型的藕煤器啊?拿著它們在內存上咔咔咔,不同大小的內存就分配好了,當然別忘了給它們取個好聽的名字。
  • 永遠不要用float
    最近有多個老師同學諮詢關於float的問題,我統一回復「永遠別用float」。這顯然是一種極端的答案,但是對於初學者和廣大ACMer來說,真的是有效的。我們可以百度一下這句話:double 和 float 兩者只差在精確度以及數值範圍,使用方法都一樣float :單精度型變量佔用4個字節,範圍是-3.4*10^38 ~~3.4*10^38,小數點有效位為7位double:雙精度型變量佔用8個字節,範圍是-1.7*10^308 ~~1.7*10^308,
  • 為什麼float後面要加f
    去年面試,筆試時有一道題是:問題:float f=3.4;是否正確?我當時真是想都沒想就填了個正確。結果就是基礎都不過關了。(我還深深地記得上大學時,教我的java老師特意在課上說過這個問題,忘得一乾二淨)對於我們碼農來說,真的是萬事都是增刪改查,都習以為常了,而java中的一些小細節可能我們都把他們忘記了,今天我就幫大家拾起java中冰山一角的float吧。
  • 小小的 float,藏著大大的學問
    可以看到:double 的尾數部分是 52 位,float 的尾數部分是 23 位,由於同時都帶有一個固定隱含位(這個後面會說),所以 double 有 53 個二進位有效位,float 有 24 個二進位有效位,所以所以它們的精度在十進位中分別是
  • php常量是什麼?它和變量有什麼區別?
    本篇將介紹php常量是什麼?它和變量有什麼區別?有興趣的朋友可以了解一下!一、前言php是一門很受歡迎的程式語言之一,它的語法簡單易學,迎來了一大批自學者,小編也是其中之一。小編自學php學了四個多月吧!雖然算不上精通,但是也算得上小有成就,獨立開發中小型網站還是不成問題的。
  • 尚學堂知識整理:Java float數據類型
    有兩種類型的浮點類型,float和double,分別表示單精度和雙精度數。它們的寬度和範圍如下所示:浮點數據類型浮點數據類型使用32位來存儲浮點數。浮點數也稱為單精度浮點數。所有以下浮點字面量表示相同的實數42.5:float數據類型定義兩個零:+0.0F(或0.0F)和-0.0F。 +0.0F和-0.0F都被認為是相等的。float數據類型定義了兩個無窮大:正無窮大和負無窮大。未定義浮點的一些操作的結果。 例如,將0.0F除以0.0F是不確定的。
  • C語言|格式控制(int、double等的輸入輸出格式與進位轉換)
    數據可以分為整形數據和實型數據,整形數據有int、long、unsigned、unsigned long,實型數據有float、double。其中整形數據在輸出時可以輸出其十進位、八進位、十六進位形式。1.
  • Double, twice和two-fold的區別
    要點1Double可以是副詞,和twice,two-fold一樣,但是double也可以作動詞,twice和two-fold不能充當動詞,Two-fold可以是形容詞,double和twice都不可以要點2double 首先可以做動詞,這是twice沒有的用法。這個時候,也有可能使用two-fold。
  • 尚學堂知識整理:Java double數據類型
    double數據類型使用64位來存儲浮點數。double值也稱為雙精度浮點數。它可以表示一個最小為4.9 x 10^-324,最大為1.7 x 10^308的數字。它可以是正的或負的。所有實數被稱為double字面量。double字面量可以可選地以d或D結尾,例如1.27d。後綴d或D在double字面量中是可選的。19.7和19.7d代表相同的double字面量。
  • 面試官:Java 中有幾種基本數據類型是什麼?
    默認 int 型,小數默認是 double 型。Float 和 Long 類型的必須加後綴。比如:float f = 100f 。基本數據類型注意事項:未帶有字符後綴標識的整數默認為int類型;未帶有字符後綴標識的浮點數默認為double類型。
  • 網頁設計中css float 屬性以及position:absolute 的區別
    文章來源:jb51網相信很多人都有這樣的問題,在頁面布局中float和position:absolute哪個更好用呢?
  • DQN系列(2): Double DQN算法原理與實現
    給出了過估計的通用原因解釋和解決方法的數學證明,最後在Atari遊戲上有超高的分數實驗表現。正常論文的閱讀方式,先看摘要和結論:為了進一步說明Q-learning, Double Q-learning估值偏差的區別,作者給出了一個有真實
  • Python和JAVA的區別
    區別:1.Python比Java簡單,學習成本低,開發效率高2.Java運行效率高於Python,尤其是純Python開發的程序,效率低3.Java相關資料多,尤其是中文資料一些細節區別:1.數python只有四種數據:整數,長整數、浮點數和複數 java則有char,short,byte,int,long,float,double類型2. 字符串2.1.
  • C語言中的乘方函數是什麼?怎麼寫?
    乘方函數名稱:pow(double,double), 具體參數中至少一方為float、double、long double類型。如計算5;時, 直接使用 pow(5,3);返回結果即記為125。我們也可以自定義乘方函數如:float power( float x,int n ) //自定義乘方函數{ int i;float s=1.0; //初始化變量s,用於存儲最終結果值for( i=1;i<=n;i++ ) //利用循環進行計算