1. 程式人生 > >Java中float/double取值範圍與精度

Java中float/double取值範圍與精度

Java浮點數

浮點數結構

  要說清楚Java浮點數的取值範圍與其精度,必須先了解浮點數的表示方法,浮點數的結構組成,之所以會有這種所謂的結構,是因為機器只認識01,你想表示小數,你要機器認識小數點這個東西,必須採用某種方法,比如,簡單點的,float四個位元組,前兩個位元組表示整數位,後兩個位元組表示小數位(這就是一種規則標準),這樣就組成一個浮點數。而Java中浮點數採用的是IEEE 754標準。

IEEE 754

  這裡就不細說什麼是IEEE 754了,就直接講具體內容,有興趣的可以自己百度。

float

符號位(S):1bit指數位(E):8bit尾數位(M):23bit

一個float4位元組32位,分為三部分:符號位,指數位,尾數位。
(1).符號位(S):最高位(31位)為符號位,表示整個浮點數的正負,0為正,1為負;
(2).指數位(E):23-30位共8位為指數位,這裡指數的底數規定為2(取值範圍:0~255)。這一部分的最終結果格式為:2E127,即範圍-127~128。另外,標準中,還規定了,當指數位8位全0或全1的時候,浮點數為非正規形式(這個時候尾數不一樣了),所以指數位真正範圍為:-126~127。
(3).尾數位(M):0-22位共23位為尾數位,表示小數部分的尾數,即形式為1.M或0.M,至於什麼時候是1,什麼時候是0,則由指數和尾數共同決定。 小數部分最高有效位是1的數被稱為正規(規格化)形式。小數部分最高有效位是0的數被稱為非正規(非規格化)形式,其他情況是特殊值。 最終float的值 = (
1)S(2E127)(1.M)
。具體形式如下:

符號

指數

部分

指數部分-127

尾數部分

小數部分的

最高有效位

形式

1

255

128

非0

沒有

NaN

1

255

128

0

沒有

負無窮

1

1~254

-126~127

任意

1

正規形式(負數)

1

0

-127

非0

0

非正規形式(負數)

1

0

-127

0

沒有

負0

0

0

-127

0

沒有

0

0

0

-127

非0

0

非正規形式(正數)

0

1~254

-126~127

任意

1

正規形式(正數)

0

255

128

0

沒有

正無窮

0

255

128

非0

沒有

NaN

double

符號位(S):1bit指數位(E):11bit尾數位(M):52bit


  double這裡就類似float,只是double的長度更大,所以範圍就更大,但規則是一樣的。double的值 = (1)S(2E1023)(1.M)

取值範圍

根據表1可知,float的取值範圍:
負無窮 —— 2128 ~~~ 2149 —— 0 —— 2149 ~~2128 —— 正無窮
1). 上面的“——”表示中間不能取值,例如負無窮到2128中間的值是取不到的(事實上128也是取不到的,只是接近近似值),但這並不是意味著,“~”任意值都能取到的,要注意,浮點數都是有精度的,並不能表示絕對值任意小的值。另外,Java中無窮大表示為:

Float.POSITIVE_INFINITY或Double.POSITIVE_INFINITY//表示正無窮大
Float.NEGATIVE_INFINITY或Double.NEGATIVE_INFINITY//負無窮大
//他們列印的結果:+/-Infinity
float f1 = (float)Math.pow(2,128);//指數>=128的,列印結果:Infinity
//上面要加(float)強制轉換,否則編譯提示出錯,詳細可參考前一節:Java變數資料型別
float f2 = (float)Math.pow(2,127);//1.7014118E38
System.out.println(Float.MAX_VALUE);//3.4028235E38
//其他測試,讀者可自行測試

2). -149的得來:看上面理論應該是150(指數全0,則指數值 = 0 -127,這個時候尾數取最小,223,則-127-23 = -150),可不知道為什麼是149,我查到的資料是說,全0,全1為特殊值,不作為範圍內的值,上面的float的最大最小值Float.MAX_VALUE都是接近2128)。故值 = (1)S(2126)(223) = +/-2149

float f3 = (float) Math.pow(2,-149)//1.4E-45,小於-149,結果則為0.0
Float.MIN_VALUE //1.4E-45

double的取值同float:
負無窮 —— 21024 ~~~ 21074 —— 0 —— 21074 ~~21024 —— 正無窮
1074 =| (-1022) - (52)|

  另外,注意表格中,還有NaN,即表示非數值,例如:

System.out.println(0.0/0.0);//列印結果:NaN。注意不能是 0/0
//NaN表示計算錯誤,具體出現情況,可以參考表中
//Float.NaN或 Double.NaN 也能直接表示NaN,NaN與其他數計算結果均為NaN,除了
Math.pow(Float.NaN,0);//結果為1.0
//另外NaN == NaN; false

浮點數精度

  精度是由尾數決定的,為什麼?由浮點數的值計算公式可知:當指數的最終值為負,雖然這個時候浮點數的值能表示更小,但這個時候僅僅能表示0~1(或-1~0)這個數段的小數,沒有實際意義。所以精度主要是看尾數的值。

float

  float的尾數:23位,其範圍為:0~223,而223=8388608=106.92,所以float的精度為6~7位,能保證6位為絕對精確,7位一般也是正確的,8位就不一定了(但不是說8位就絕對不對了),注意這裡的6~7位是有效小數位(大的數你先需要轉換成小數的指數形式,例如:8317637.5,其有效小數位:8.3176375E6,七位),而有效位(從第一個不為0的開始數)是7~8位,是包括整數位的,像8317637.5,你不轉換,則要從有效位的角度來看,有8位有效位。
  

System.out.println((float)Math.pow(10,6.92));//注意加float強制轉換
//列印結果8317637.5,float只保證7~8位有效位,其餘位數舍入

  不理解的話,可以再這樣想:23位,二進位制0101……0101,尾數表示小數位,最小為0000……0001(22個0,最後一個1),即223=1.1920929E-7 ,這是float的最小單元(大概是0.0000001192大小,你想表示比這更小的,比如0.00000001,不可能啊),這是一個7位小數位小數,最小就是這麼小,比這個更小的,計算機就無能為力了,比這個更大的,每次通過加這麼一個最小單元,直到相等或接近(兩個相差一個最小單元的數,它們之間的數也是不能表示的,所以有的7位也是不能精確的,因為最小不是0.0000001,而是比這個稍大)。

double

  計算方式同float,double的尾數:52位,252=2.220446049250313E-16,最小是16位,但最小不是1.0E-16,所以精度是15~16,能保證15,一般16位。
  更多關於Java浮點數的,可以參考這裡:基礎野:細說浮點數(肥子John)

相關推薦

Javafloat/double範圍精度

Java浮點數 浮點數結構   要說清楚Java浮點數的取值範圍與其精度,必須先了解浮點數的表示方法,浮點數的結構組成,之所以會有這種所謂的結構,是因為機器只認識01,你想表示小數,你要機器認識小數點這個東西,必須採用某種方法,比如,簡單點的,float

Javafloat範圍

規格化表示       java中的浮點數採用的事IEEE Standard 754 Floating Point Numbers標準,該標準的規範可以參考http://blog.csdn.net/treeroot/articles/94752.aspx.      float佔用4個位元組,和int是一樣,

Javafloat範圍為什麼是那麼大?

float佔用4個位元組,和int是一樣,也就是32bit.       第1個bit表示符號,0表示正數,1表示負數,這個很好理解,不用多管.       第2-9個bit表示指數,一共8為(可以表示0-255),這裡的底數是2,為了同時表示正數和負數,這裡要減去127的

Java float範圍

.    float佔用4個位元組,和int是一樣,也就是32bit.    第1個bit表示符號,0表示正數,1表示負數,這個很好理解,不用多管.    第2-9個bit表示指數,一共8位(可以表示0-255),這裡的底數是2,為了同時表示正數和負數,這裡要減去127的偏移量.這樣的話範圍就是(-127到1

C#float範圍精度分析

windows系統 weight 3.5 ans adding 發生 mage 深入 wid 本文實例分析了C#中float的取值範圍和精度。分享給大家供大家參考。具體分析如下: float類型的表現形式: 默認情況下,賦值運算符右側的實數被視為 double。 因此

javashort、int、long、floatdouble範圍

對於java的資料型別,既熟悉又陌生,於是整理了這篇文件。最近的面試讓我開始注意細節,細節真的很重要。一、分析基本資料型別的特點,最大值和最小值。1、基本型別:int 二進位制位數:32包裝類:java.lang.Integer最小值:Integer.MIN_VALUE=

Java語言基礎longfloat範圍誰大誰小

結論 float的取值範圍比long大 驗證 public class Test1_DataTypeConversion { public static void main(Stri

float/double範圍-轉換-精度理解- C語言

float與double的範圍和精度1 範圍float和double的範圍是由指數的位數來決定的。float的指數位有8位,而double的指數位有11位,分佈如下:float:1bit(符號位)8bits(指數位)23bits(尾數位)double:1bit(符號位)11bits(指數位)52bits(尾數

java資料型別,範圍,引用型別解析

    與javascript不同,Java是強型別語言,在定義變數前需要宣告資料型別。主要分兩種資料型別:基本資料型別和引用資料型別。   1、基本資料型別分析:   基本資料型別

Java基本資料型別範圍,為什麼String 不是基本資料型別,char的範圍為什麼沒有負數

一、在JAVA中一共有八種基本資料型別,他們分別是 byte、short、int、long、float、double、char、boolean 整型 其中byte、short、int、long都是表示整數的,只不過他們的取值範圍不一樣 byte的取

javafloat,double型別運算的處理

public class Test{ public static void main(String args[]){ System.out.println(0.05+0.01); System.out.println(1.

javafloatdouble範圍

float:4位元組(32bit),IEEE 754. 範圍:[-3.40282346638528860e+38 , -1.40129846432481707e-45] ∪ [1.40129846432481707e-45 ~ 3.40282346638528860e+38]

java floatdouble型別資料詳解

1、定義標準 IEEE754 在IEEE754標準中進行了單精度浮點數(float)和雙精度數浮點數(double)的定義。 float有32bit,double有64bit。它們的構成包括符號位

java為什麽byte的範圍是-128到+127

進制數 符號位 為什麽 絕對值 www .html tar 同學 自己 概念:java中用補碼表示二進制數,補碼的最高位是符號位,最高位為“0”表示正數,最高位為“1”表示負數。正數補碼為其本身;負數補碼為其絕對值各位取反加1

JAVA基本類型大小範圍?

false 特殊 數據類型 字節 true ima 指令 它的 ges 布爾類型boolean比較特殊,盡管Java虛擬機定義了boolean類型,但虛擬機對boolean類型的支持是有限的,沒有為boolean值單獨設計JVM指令。操作布爾值的表達式在編譯之後,它使用的

如何理解IEEE 754標準對Javafloatdouble的規定

rac tro zh-cn 分享圖片 編號 如何 ins font 指數 在Java語言中,我們可以使用float和double這兩種基本數據類型來表示特定的數據。 這兩種數據類型,本質上是浮點數(floating-point number),浮點是一種對於實數的近似值數值

java int 型別的範圍

int 是整型,對應我們數學上認識的數值為整數,就是沒有小數點的數。 在計算機系統中,我們為這種型別的數定了一個範圍(其實我們為每一種型別都定了範圍,至於這個範圍是多少.....(當然不能那麼快說)。 為什麼要有這個範圍的限制呢,這是為了物盡所用,不能浪費。打個比方,我

關於JavaByte型別的範圍是-128~127的理解

學習C語言的時候對int類型範圍理解得不透徹,所以通過網上查詢資料,結合大牛的講解分析了一下byte型別的範圍,希望可以幫到大家。 1、知識理解 在計算機內,定點數有3種表示法:原碼、反碼和補碼

關於float/double範圍和表示

1.float和double的範圍和精度        float和double的範圍是由指數的位數來決定的。float的指數位有8位,而double的指數位有11位,分佈如下:float:1bit(符號位)+8bits(指數位+23bits(尾數位)double:1bit(

Java,為什麼byte型別的範圍為-128~127?

在學習Java基礎語法的時候,初學者的我們可能都會有這麼一個疑問為什麼byte型別的取值範圍為什麼是[-128,127]而不是[-127,127]。01111111表示最大的數值:127,因為第一位是符號位,所以11111111應該是最小的數值:-127,不是這