❶ float和double型分別怎麼存儲
C/C++的浮點數據類型有float和double兩種。
類型float大小為4位元組,即32位,內存中的存儲方式如下: 符號位(1 bit) 指數(8 bit) 尾數(23 bit)
類型double大小為8位元組,即64位,內存布局如下: 符號位(1 bit) 指數(11 bit) 尾數(52 bit)
符號位決定浮點數的正負,0正1負。
指數和尾數均從浮點數的二進制科學計數形式中獲取。
如,十進制浮點數2.5的二進制形式為10.1,轉換為科學計數法形式為(1.01)*(10^1),由此可知指數為1,尾數(即科學計數法的小數部分)為01。
根據浮點數的存儲標准(IEEE制定),float類型指數的起始數為127(二進制0111 1111),double類型指數的起始數為1023(二進制011 1111 1111),在此基礎上加指數,得到的就是內存中指數的表示形式。尾數則直接填入,如果空間多餘則以0補齊,如果空間不夠則0舍1入。所以float和double類型分別表示的2.5如下(二進制):
符號位
指數
尾數
0
1000 0000
010 0000 0000 0000 0000 0000
0
100 0000 0000
0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
❷ IEEE 754啥意思java中float和double的存儲方式就是用IEEE 754表示嗎通俗一點講講,必採納
IEEE二進制浮點數算術標准(IEEE 754)是最廣泛使用的浮點數運算標准,它規定了四種表示浮點數值的方式:單精確度(32位元)、雙精確度(64位元)、延伸單精確度(43位元以上,很少使用)與延伸雙精確度(79位元以上,通常以80位元實做)。
2.1 實數的IEEE 754表示形式
一個實數V在IEEE 754標准中可以用V=(-1)s×M×2E 的形式表示[3,4],說明如下:
(1)符號s(sign)決定實數是正數(s=0)還是負數(s=1),對數值0的符號位特殊處理。
(2)有效數字M(significand)是二進制小數,M的取值范圍在1≤M<2或0≤M<1。
(3)指數E(exponent)是2的冪,它的作用是對浮點數加權。
2.2 浮點格式
浮點格式是一種數據結構,它規定了構成浮點數的各個欄位,這些欄位的布局,及其算術解釋[2]。IEEE 754浮點數的數據位被劃分為3個欄位,對以上參數值進行編碼:
(1)一個單獨的符號位s直接編碼符號s。
(2)k位的偏置指數e(e=ek-1…e1e0)編碼指數E,移碼表示。
(3)n位的小數f(fraction)(f=fn-1…f1f0)編碼有效數字M,原碼表示。
2.3 浮點數的分類
根據偏置指數e的值,被編碼的浮點數可分成三種類型。
(1)規格化數
當有效數字M在范圍1≤M<2中且指數e的位模式ek-1…e1e0既不全是0也不全是1時,浮點格式所表示的數都屬於規格化數。這種情況中小數f(0≤f<1 ) 的二進製表示為0. fn-1…f1f0。有效數字M=1+f,即M=1. fn-1…f1f0 (其中小數點左側的數值位稱為前導有效位) 。我們總是能調整指數E,使得有效數字M在范圍1≤M<2中,這樣有效數字的前導有效位總是1,因此該位不需顯示表示出來,只需通過指數隱式給出。
需要特別指出的是指數E要加上一個偏置值Bias,轉換成無符號的偏置指數e,也就是說指數E要以移碼的形式在存放計算機中。且e、E和Bias三者的對應關系為e=E+Bias,其中Bias=2k-1-1。
(2)非規格化數
當指數e的位模式ek-1…e1e0全為零(即e=0)時,浮點格式所表示的數是非規格化數。這種情況下,E=1-Bais,有效數字M=f=0. fn-1…f1f0 ,有效數字的前導有效位為0。
非規格化數的引入有兩個目的。其一是它提供了一種表示數值0的方法,其二是它可用來表示那些非常接近於0.0的數。
(3)特殊數
當指數e的位模式ek-1…e1e0全為1時,小數f的位模式fn-1…f1f0全為0(即f=0)時,該浮點格式所表示的值表示無窮,s=0 時是+∞,s=1時是-∞。
當指數e的位模式ek-1…e1e0全為1時,小數f的位模式fn-1…f1f0不為0(fn-1、…、f1、f0、至少有一個非零即f≠0)時,該浮點格式所表示的值被稱為NaN(Not a Number)。比如當計算 或∞-∞時用作返回值,或者用於表示未初始化的數據。
3 IEEE 754浮點存儲格式
與浮點格式對應,浮點存儲格式規定了浮點格式在存儲器中如何存放。IEEE標準定義了這些浮點存儲格式,但具體選擇哪種存儲格式由實現工具(程序設計語言)決定。
匯編語言軟體有時取決於所使用的存儲格式,但更高級的語言通常僅處理浮點數據類型的語言概念。這些浮點數據類型在不同高級語言中有不同的名字,相應的IEEE格式如表1。
表1 IEEE 格式和語言類型
IEEE精度 C,C++ FORTRAN
單精度 float REAL or REAL*4
雙精度 double DOUBLE PRECISION or REAL*8
擴展雙精度 long double REAL*16 [僅適用於SPARC和PowerPC]
IEEE 754標准准確地定義了單精度和雙精度浮點格式,並為這兩種基本格式的分別定義了擴展格式,表1里擴展雙精度格式是IEEE標準定義的擴展雙精度類中的一種。
下面詳細討論在Intel x86和SPARC平台上使用的三種IEEE浮點存儲格式。
3.1 單精度格式
IEEE單精度浮點格式共32位,包含三個構成欄位:23位小數f,8位偏置指數e,1位符號s。將這些欄位連續存放在一個32位字里,並對其進行編碼。其中0:22位包含23位的小數f; 23:30位包含8位指數e;第31位包含符號s。如圖1所示。
圖1 單精度存儲格式
一般地,32位字的第0位存放小數f的最低有效位LSB(the least significant bit),第22位存放小數f的最高有效位MSB(the most significant bit);第23位存放偏置指數的最低有效位LSB,第30位存放偏置指數的最高有效位MSB;最高位,第31位存放符號s。
3.2 雙精度格式
IEEE雙精度浮點格式共64位,佔2個連續32位字,包含三個構成欄位:52位的小數f,11位的偏置指數e,1位的符號位s。將這2個連續的32位字整體作為一個64位的字,進行重新編號。其中0:51位包含52位的小數f;52:62位包含11位的偏置指數e;而最高位,第63位包含符號位s。如圖2所示。
圖 2 雙精度浮點數的存儲格式
f[31:0]存放小數f的低32位,其中第0位存放整個小數f的最低有效位LSB,第31位存放小數f的低32位的最高有效位MSB。
在另外的32位的字里,第0 到19位,即f[51:32],存放小數f的最高的20位,其中第0位存放這20位最高有效數中的最低有效位LSB,第19位存放整個小數f的最高有效位MSB。第20到30位,即e[52:62],存放11位的偏置指數e,其中第20位存放偏置指數的最低有效位LSB,第30位存放最高有效位MSB。最高位,第31位存放符號位s。
在Intel x86結構計算機中,數據存放採用小端法(little endian),故較低地址的32位的字中存放小數f的f[31:0]位。而在在SPARC結構計算機中,因其數據存放採用大端法(big endian),故較高地址的32位字中存放小數f的f[31:0]位。
3.3 擴展雙精度格式
⑴ 擴展雙精度格式(SPARC 結構計算機)
該4倍精度浮點環境符合IEEE關於擴展雙精度格式的定義。該浮點環境的4倍精度浮點格式共128位,佔4個連續32位字,包含3個構成欄位:112位的小數f,15位的偏置指數e,和1位的符號s。將這4個連續的32位字整體作為一個128位的字,進行重新編號。其中0:110位包含小數f;112:126位包含偏置指數e;第127位包含符號位s。如圖3所示。
在SPARC結構計算機中,地址最高的32位字存放小數的32位最低有效位,即f[31:0];但是在PowerPC結構計算機中,卻是地址最低的32位字存放這些位。
緊鄰的兩個32位字(在SPARC機中向下計算,在PowerPC機中向上計算)分別存放f[63:32]和f[95:64]。
最後一個字的第0到15位存放小數的最高16位,即f[111:96]。其中第0位存放該16位的最低有效位,第15位存放整個小數f的最高有效位。第16到30位存放15位的偏置指數e,其中第16位存放偏置指數的最低有效位,第30位存放它的最高有效位。最高位,第31位存放符號s。
圖 3 擴展雙精度存儲格式 (SPARC 結構計算機)
⑵ 擴展雙精度格式(Intel x86結構計算機)
該浮點環境雙精度擴展格式符合IEEE雙精度擴展格式的定義。該浮點環境的擴展雙精度格式共80位,佔3個連續32位字,包含四個構成欄位:63位的小數f,1位顯式前導有效位(explicit leading significand bit)j,15位偏置指數e,和1位符號位s。將這3個連續的32位字整體作為一個96位的字,進行重新編號。其中0:63包含63位的小數f,第63位包含前導有效位j,64:78位包含15位的偏置指數e,最高位第79位包含符號位s。
在Intel結構系計算機中,這些欄位依次存放在十個連續的位元組中。但是,由於 UNIX System V Application Binary Interface Intel 386 Processor Supplement (Intel ABI) 要求雙精度擴展參數,從而佔用堆棧中3個相連地址的32位字,其中最高一個字的高16位未被使用,如圖4所示。
圖4 擴展雙精度存儲格式(Intel x86結構計算機)
地址最低的32位字存放小數f的低32位,即f[31:0]。其中第0位存放整個小數f的最低有效位LSB 第31位存放小數低32位的最高有效位MSB。
地址居中的32位字,第0到30位存放小數f的31位最高位,即f[62:32]。其中第0位存放31位最高小數位的最低有效位LSB,第30位存放整個小數的最高有效位,地址居中的32位字的最高位第31位存放顯式的前導有效位j。
地址最高32位字里,第0到14位存放15位的偏置指數e,第0位存放偏置指數的最低有效位LSB,第14位存放最高有效位MSB,第15位存放符號位s。雖然地址最高的32位字的高16位在Intel x86結構系列機種未被使用,但他們對符合Intel ABI的規定來說,是必需的。
4 總結
以上討論了Intel x86、Power PC和SPARC平台上使用的三種IEEE 754浮點數格式及其存儲格式,下面對浮點數的相關參數進行總結,具體見表2。
表2 IEEE 浮點格式參數總結
參數 浮點格式
單精度 雙精度 擴展雙精度(Intel x86) 擴展雙精度(SPARC)
小數f寬度n 23 52 63 112
前導有效位 隱含 隱含 顯式 隱含
有效數字M精度p 24 53 64 113
偏置指數寬度k 8 11 15 15
偏置值Bias +127 +1023 +16383 +16383
符號位寬度 1 1 1 1
存儲格式寬度 32 64 80 128
參考文獻
[1] David Goldberg with Doug Priest. What Every Computer Scientist Should Know about Floating-Point Arithmetic. http://grouper.ieee.org/
[2] Sun Corporation.Numerical Computation Guide, pp1-11. http://docs.sun.com
[3] Randal E.Bryant,David O'Hallaron. Computer Systems Aprogrammer』s Perspective(英文版) [M] .北京:電子工業出版社,2004
[4]David A. Patterson, John L. Hennessy.Computer Organization & Design: The Hardware/Software Interface. (英文版 第二版) [M] . 北京:機械工業出版社,1999.275~321
❸ 浮點類型是如何存儲的
計算機中最小的存儲單位是bit只能保存0和1,整數在內存中如何存儲我們都知道,將要存儲的數字轉成2進制即可
用windows自帶的計數器可以方便的查看整數對應的2進制值
如:
byte類型(單位元組)
那浮點類型是如何用這么少的位元組(如float 4位元組)表示這么大(float 最大 3.4028235E38)的數字呢?
浮點數,是屬於有理數中某特定子集的數的數字表示,在計算機中用以近似表示任意某個實數。具體的說,這個實數由一個整數或定點數(即尾數)乘以某個基數(計算機中通常是2)的整數次冪得到,這種表示方法類似於基數為10的科學計數法。
科學計數法是一種記數的方法。把一個數表示成a與10的n次冪相乘的形式(1≤|a|<10,a不為分數形式,n為整數),這種記數法叫做科學計數法。當我們要標記或運算某個較大或較小且位數較多時,用科學計數法免去浪費很多空間和時間。
這也是一種目前最常用的浮點數標准!為許多CPU與浮點運算器所採用。
簡單的說就是將一個浮點數字拆成3個部分(符號部分、指數部分、小數部分) 存儲在連續的bit中,類似科學計數法。
用 {S,E,M}來表示一個數 V 的,即 V =(-1)S × M × 2E ,如下:
其中:
其中d.dd...d 為有效數字,β為基數,e 為指數
有效數字中 數字的個數 稱為 精度 ,我們可以用 p 來表示,即可稱為 p 位有效數字精度。
每個數字 d 介於 0 和基數 β 之間,包括 0。
對十進制的浮點數,即基數 β 等於 10 的浮點數而言,上面的表達式非常容易理解。
如 12.34,我們可以根據上面的表達式表達為:
1×10 1 + 2×10 0 + 3×10 -1 + 4×10 -2
其規范的浮點數表達為: 1.234×10 1 。
但對二進制來說,上面的表達式同樣可以簡單地表達。
唯一不同之處在於:二進制的 β 等於 2,而每個數字 d 只能在 0 和 1 之間取值。
如二進制數 1001.101 ,我們可以根據上面的表達式表達為:
1×2 3 + 0×2 2 + 0×2 1 + 1×2 0 + 1×2 -1 + 0×2 -2 + 1×2 -3
其規范浮點數表達為: 1.001101×2 3 。
二進制數 1001.101 轉成十進制如下:
由上面的等式,我們可以得出:
向左移動二進制小數點一位相當於這個數除以 2,而向右移動二進制小數點一位相當於這個數乘以 2。
如 101.11 = 5又3/4 (5.75),向左移動一位,得到 10.111 = 2又7/8 (2.875)。
除此之外,我們還可以得到這樣一個基本規律:
一個十進制小數要能用浮點數精確地表示,最後一位必須是 5(當然這是必要條件,並非充分條件)。
如下面的示例所示:
基本換算方法:
將10進制的數拆分成整數和小數兩個部分
整數部分除以2,取余數;小數部分乘以2,取整數位。
示例:
將十進制 1.1 轉成 二進制
整數部分:1
1
小數部分:0.1
二進制形式表示為:
1.000110011001100110011...
再加上整數1,約等於:
1.099609375
計算的位數越多越精確
注意:
二進制小數不像整數一樣,只要位數足夠,它就可以表示所有整數。
在有限長度的編碼中,二進制小數一般無法精確的表示任意小數,比如十進制小數0.2,我們並不能將其准確的表示為一個二進制數,只能增加二進制長度提高表示的精度。
根據 IEEE 754 浮點「雙精度格式」位布局。
如果參數是正無窮大,則結果為 0x7ff0000000000000L。
如果參數是負無窮大,則結果為 0xfff0000000000000L。
如果參數是 NaN,則結果為 0x7ff8000000000000L。
根據 IEEE 754 浮點「單一格式」位布局。
如果參數為正無窮大,則結果為 0x7f800000。
如果參數為負無窮大,則結果為 0xff800000。
如果參數為 NaN,則結果為 0x7fc00000。
這里以 double類型說明
將一個浮點數與上面的掩碼進行與運算,即可得到對應的 符號位、指數位、尾數位 的值。
1.000110011001100110011...
所以存為:
0 01111111111 000110011001100110011...
根據 IEEE 754 規范
在二進制,第一個有效數字必定是「1」,因此這個「1」並不會存儲。
單精和雙精浮點數的有效數字分別是有存儲的23和52個位,加上最左邊沒有存儲的第1個位,即是24和53個位。
通過計算其能表示的最大值,換十進制來看其精度:
浮點運算很少是精確的,只要是超過精度能表示的范圍就會產生誤差。而往往產生誤差不是因為數的大小,而是因為數的精度。
我自己理解為分兩種情況(這個不一定是對)
通過上面的轉換示例,我們知道小數的二進製表示一般都不是精確的,在有限的精度下只能盡量的表示近似值
值本身就不是精確的,再進行計算就很可能產生誤差
輸出:
0.1
原始值: 0 01111111011
指數:1019 -1023 = -4
二進制形式:
0.0001
0.2
原始值:0 01111111100
指數:1020 -1023 = -3
二進制形式:
0.00
0.3
原始值:0 01111111101
指數:1021 = -2
二進制形式:
0.00
二進制加法運算
這里用float驗證,float最大的精度是8位數
對於不能精確的表示的數,採取一種系統的方法:找到「最接近」的匹配值,它可以用期望的浮點形式表現出來,這就是舍入。
對於舍入,可以有很多種規則,可以向上舍入,向下舍入,向偶數舍入。如果我們只採用前兩種中的一種,就會造成平均數過大或者過小,實際上這時候就是引入了統計偏差。如果是採用偶數舍入,則有一半的機會是向上舍入,一半的機會是向下舍入,這樣子可以避免統計偏差。而 IEEE 754 就是採用向最近偶數舍入(round to nearest even)的規則。
(這段是網上抄的)
這里以java語言示例,用大端的方式示例(網路序)
java中是以大端模式存儲的,java對我們屏蔽了內部位元組順序的問題以實現跨平台!
實際在不同的cpu架構下,存儲方式不同,我們常用的X86是以小端的模式存儲的。
網路傳輸一般採用大端序,也被稱之為網路位元組序,或網路序。IP協議中定義大端序為網路位元組序。
輸出:
❹ 讀取和保存一個二維double數組用Java語言如何做
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class NewTxt {
public static void main(String[] args) throws IOException {
int n = 5; //N*N數組
double[][] arr = new double[n][n]; //插入的數組
double[][] arr2 = new double[n][n];; //讀取出的數組
//數組初始化,隨機生成的[0,100)之間的double數
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr[i][j] = Math.random()*100;
System.out.println(arr[i][j]);
}
}
File file = new File("d:\\array.txt"); //存放數組數據的文件
FileWriter out = new FileWriter(file); //文件寫入流
//將數組中的數據寫入到文件中。每行各數據之間TAB間隔
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
out.write(arr[i][j]+"\t");
}
out.write("\r\n");
}
out.close();
BufferedReader in = new BufferedReader(new FileReader(file)); //
String line; //一行數據
int row=0;
//逐行讀取,並將每個數組放入到數組中
while((line = in.readLine()) != null){
String[] temp = line.split("\t");
for(int j=0;j<temp.length;j++){
arr2[row][j] = Double.parseDouble(temp[j]);
}
row++;
}
in.close();
//顯示讀取出的數組
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
System.out.print(arr2[i][j]+"\t");
}
System.out.println();
}
}
}
❺ java中double類數組要怎樣才能精確到有幾位小數點
double的表示方式如下:
符號位(1位)
|
指數(11位,1位符號位+10位指數位)
|
尾數(52位)
存儲方式是按照浮點的形式存儲,所以不存在整數部分和小數部分。比如1678.3456
=
1.6783456
*
10^3,但計算機只認識0、1,所以要將其轉化成二進制小數,我們不管轉換後的結果如何,轉換後得到的浮點數形式肯定是這種1.xxxxxx
*
2
^
y,其中xxxxxx表示小數部分,就是尾數,而小數點前面始終是1,可以不存儲,y就是指數部分。
所以上面的1.xxxxxx
*
2^y在計算機中就表示為:
0
|
y
+
127
|
xxxxxx
最前面的符號位為0表示正;指數存儲時要加上127;xxxxxx就是尾數。
float的表示方法類似,只是位數不一樣,如下:
符號位(1位)
|
指數(8位)
|
尾數(23位)
❻ Java 中Double的疑問
你的理解是錯誤的,double型是64位,但是表示方法和整數是不一樣的。你用整數的想法去理解浮點數,肯定會出錯啦。給你看下我做過的筆記,你理解下:
存儲布局就是一個浮點數在內存中如何表示.我們知道浮點數有float和double,前者是4個位元組也就是32位,後者是8個位元組也就是64位.布局分別為:
符號 指數 小數部分 偏移附加(bias)
單精度 1[31] 8[30-23] 23[22-00] 127
雙精度 1[63] 11[62-52] 52[51-00] 1023
中括弧內為位的編號范圍,外面為該部分所佔有的位的數量.偏移附加不屬於位表示的內容,是一個常量,稍後解釋.
符號只有一位:0-表示正數 1-表示負數
指數部分:用指數部分的值(8位/11位,unsigned)的值 減去 偏移附加 得到該數實際的指數 例如值為200,實際指數為73=200-127.對於雙精度的double來說常量bias=1023
尾數:尾數是什麼?對於一個科學計數法來講,形式象這樣的 L.M×BE,那麼這個L.M就是所謂的尾數(mantisa).它由一個起始位和一個小數部分組成.