1. 浮點數 在計算機內的存儲形式
浮點數不難,但是要想記熟還真有點不容易,多琢磨琢磨。
一般情況下,浮點數的表示有一下幾個要點:
1、要規格化(讓浮點數表示結果唯一),因為100=10^2 = 0.1 * 10^3, 所以第一步要統一地規格化,確定「階數」和「尾數」(尾數在0.5-1之間,也就是二進制的0.1-1.0之間)
2、「階碼」一般用「移碼」表示法,而「尾數」一般用「原碼/補碼表示法,「數符」表示浮點數的正副號
3、浮點數的形式: 「符號位」【應該就是『數符』】+「階碼」+「尾數「
--浮點數的表示按照不同地標准,表示方法不同,你的原問題沒講清楚用什麼格式表示,我就用最常用地格式來理解了
------------------
其實就以上兩點,計算機中「『帯符號數』的表示」有四種:原碼、補碼、反碼、移碼,這些都是基礎知識,可以自己去看一下這四種表示方法,就自然明白「階符、數符」這些相當於「符號位」的作用了。
先簡單講一下吧,你再結合詳細資料看吧:【設所表示的都是定點純小數】
(小數點前面可以看成是「符號位」,也就對應原來地「階符」和「數符」)
原碼:0.11表示0.75(2^-1 + 2 ^-2), 1.11表示 『-0.75』(前面的1相當於符號位,表示這個數是負數,也就是說「符號位是0」表示正數,1表示負數)
補碼:最普遍地就是補碼了 0.11表示0.75, 1.11表示『-0.25』(也是「0」為正數,1為負數。和原碼地規律一樣)
反碼,最簡單了:正數不變,負數對每一位『取反』即可,0.11=0.75,1.10=-0.25(即0.01地相反數)
-------------以上三種表示方法,對正數的情況都不做處理,但是移碼表示法要對正數做處理。
移碼:1.01=0.25,而0.01=-0.75
。移碼復雜一點,他的表示方法是: 移碼= 2^階碼位數 + 真值(真值:指原來那個『帯符號數』,注意要把把正副號帶入計算)
-----------------------------------
N=-0.110101x2^100: 階數是「正100」,尾數是「負0.110101」,所以整個浮點數是個負數,所以第一位是「1」【第一個符號位-「數符」表示『尾數的正負號』】
階碼是「10 0100」【移碼表示法,最高位是「符號位」】
所以,應該表示為: 1(符號位) 100100(階碼的移碼表示) 11010100【尾數和符號位結合起來,用的是原碼表示法】
2. 浮點數的存儲結構是怎樣的
浮點數存儲時有符號位,階數位和尾數三部分組成。
解:最大的正數= (1-2 ^ (7))x 2 ^ (2 ^ (3) - 1) = (1-2 ^ (7)) x 2 ^(7) = 127,規則最小的正數=2×2^(-1)(或2^(3))x^2=2-1=2^(8)(9)=1/512。
最明顯的絕對值是-1*2^(2^3-1)也就是-1*2^7,也就是-128。
(2)浮點數存儲方式ppt擴展閱讀:
浮點數A由兩個數字m和e表示:A=m*b^e。在任何這樣的系統中,我們選擇基數b(計數系統的基礎)和精度p(要存儲的比特數)。
M(即尾數)的形狀為±d.dd…DDD的p位(每個位是0和b-1之間的整數,包括0和b-1)。如果m的第一個數字是一個非零整數,那麼m就被歸一化了。
一些描述使用單個符號位(s表示+或-)表示加號或減號,因此m必須是正數。E是a的指數。
結構:
表示計算機中的一個浮點數,其結構如下:
尾數部分(定點小數)指令碼部分(定點整數)
3. 浮點類型是如何存儲的
計算機中最小的存儲單位是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協議中定義大端序為網路位元組序。
輸出:
4. 浮點型數據在內存中實際的存放形式(儲存形式)
浮點型數據在內存中存儲不是按補碼形式,是按階碼的方式存儲,所以雖然int和float都是佔用了4個位元組,如果開始存的是int型數據,比如是個25,那麼用浮點的方式輸出就不是25.0,也許就變的面目全非。
你可以用共用體的方式驗證一下。在公用體中定義一個整形成員變數和一個浮點型成員變數,給整形賦值25,輸出浮點成員變數,你就知道了。
5. 請問浮點型數據在計算機是怎麼存儲的
對於浮點類型的數據採用單精度類型(float)和雙精度類型(double)來存儲,float數據佔用32bit,double數據佔用64bit。
無論是單精度還是雙精度在存儲中都分為三個部分:
1、符號位(Sign) : 0代表正,1代表為負。
2、指數位(Exponent):用於存儲科學計數法中的指數數據,並且採用移位存儲。
3、尾數部分(Mantissa):尾數部分。
(5)浮點數存儲方式ppt擴展閱讀
實型變數分為兩類:單精度型和雙精度型,
其類型說明符為float 單精度說明符,double
雙精度說明符。在Turbo
C中單精度型佔4個位元組(32位)內存空間,其數值范圍為3.4E-38~3.4E+38,只能提供七位有效數字。
雙精度型佔8
個位元組(64位)內存空間,其數值范圍為1.7E-308~1.7E+308,可提供16位有效數字。
實型變數說明的格式和書寫規則與整型相同。
例如: float x,y; (x,y為單精度實型量)
double a,b,c; (a,b,c為雙精度實型量)
實型常數不分單、雙精度,都按雙精度double型處理。
6. 浮點數的存儲問題
先看看浮點數格式
·一個浮點數總共有4個位元組,32位
第一個比特表符號 0正數 1負數
後八個比特表階碼,即為指數,這個數在實際的數上面加127
最後23個比特表尾數 原碼表示
具體分析
對於3.25
正數 首位為0
用二進製表示 11.01=1.101乘以2的1次方
所以階碼為1 127+1=128
10000000
對於尾數1.101,因為規格化的數都是最高位為1,即小數點左邊的數為1
所以這個1就省略,因此存儲的時候就存101
即
10100000 00000000 0000000
把所有的拼起來
01000000 01010000 00000000 00000000
你的上面最後寫反了
7. 浮點數在計算機中的存儲方式中,指數位為什麼是採用「移位存儲」方式怎麼看出來是用「移位存儲」
不論是float還是double在存儲方式上都是遵從IEEE的規范的.
float遵從的是IEEE R32.24 ,而double 遵從的是R64.53。
浮點數保存的位元組格式如下:
地址 +0 +1 +2 +3
內容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
這里
S 代表符號位,1是負,0是正
E 偏移127的冪,二進制階碼=(EEEEEEEE)-127。
M 24位的尾數保存在23位中,只存儲23位,最高位固定為1。此方法用最較少的位數實現了
較高的有效位數,提高了精度。
零是一個特定值,冪是0 尾數也是0。
浮點數-12.5作為一個十六進制數0xC1480000保存在存儲區中,這個值如下:
地址 +0 +1 +2 +3
內容0xC1 0x48 0x00 0x00
浮點數和十六進制等效保存值之間的轉換相當簡單。下面的例子說明上面的值-12.5如何轉
換。
浮點保存值不是一個直接的格式,要轉換為一個浮點數,位必須按上面的浮點數保存格式表
所列的那樣分開,例如:
地址 +0 +1 +2 +3
格式 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
二進制 11000001 01001000 00000000 00000000
十六進制 C1 48 00 00
從這個例子可以得到下面的信息:
符號位是1 表示一個負數
冪是二進制10000010或十進制130,130減去127是3,就是實際的冪。
尾數是後面的二進制數10010000000000000000000
在尾數的左邊有一個省略的小數點和1,這個1在浮點數的保存中經常省略,加上一個1和小數
點到尾數的開頭,得到尾數值如下:
1.10010000000000000000000
接著,根據指數調整尾數.一個負的指數向左移動小數點.一個正的指數向右移動小數點.因為
指數是3,尾數調整如下:
1100.10000000000000000000
結果是一個二進制浮點數,小數點左邊的二進制數代表所處位置的2的冪,例如:1100表示
(1*2^3)+(1*2^2)+(0*2^1)+(0*2^0)=12。
小數點的右邊也代表所處位置的2的冪,只是冪是負的。例如:.100...表示(1*2^(-1))+
(0*2^(-2))+(0*2^(-2))...=0.5。
這些值的和是12.5。因為設置的符號位表示這數是負的,因此十六進制值0xC1480000表示-
12.5。
下面給個例子
#include <stdio.h>
union FloatData
{
float f;
unsigned char h[4];
};
void main(void)
{
FloatData t;
float temp = 0;
printf(