iT邦幫忙

0

SQL FLOAT 只有4個BYTE為什麼可以儲到15個位數的數字

問題1-1(未完成)
float:浮點型,BYTE=4,32bit
BYTE=4,32bit 2的32平方,算起來是4294967296
但為什麼它可以儲存到15位數的精準呢?

DECLARE @NUMBER FLOAT =999999999999999 --15位.如果加上去變16位,就會無法精準.
SELECT @NUMBER ,@NUMBER +1,CAST(@NUMBER AS DECIMAL(38,0))	
--RESULT 999999999999999, 1E+15 ,999999999999999

Ans:
要先知道它怎麼被save在記憶體裡.
float:浮點型,BYTE=4,32bit
1:拿來save正負號
2~9:拿來save 小數點的位子 127當做中心點.128表示往右移.126表示往左移.
10~32:拿來儲1之後的小數點

問題1-2
若BYTE=8,64bit 2的64平方,算起來是1884744073709151616

但為什麼它只有15位數的精準呢?

DECLARE @NUMBER FLOAT(53) =1999999999999999 --15位.如果加上去變16位,就會無法精準.
SELECT @NUMBER ,@NUMBER +1,CAST(@NUMBER AS DECIMAL(38,0))	
--RESULT 2E+15, 2E+15 ,999999999999999

問題1-3(已答)
假設1byte
111111 = 11
會記錄成1.11111(小數點記在1個1的後面)
那如果是0.8=0.11001100 ,那也會記成1.10011001100嗎?
Ans:會

問題1-4(已答)
1100 >1.100E3 右移3
0.11001100 1.10011E1 怎麼知道要左移呢?1.10011E-1嗎?那-1記錄在哪裡?
Ans:
這影片教人家怎麼把數字轉成IEEE
https://www.youtube.com/watch?v=8afbTaA-gOQ&t=52s

問題1-4(已答)
怎麼0.000123怎麼轉成2進位?
要將10進位小數變成2進位
只要將小數部分一直乘 2
把整數部分依序記下來即可
Ans :
0.9 *2 = 1.8 記 1
0.8 *2 = 1.6 記 1
0.6 *2 = 1.2 記 1
0.2 *2 = 0.4 記 0
0.4 *2 = 0.8 記 0
0.8 *2 = 1.6 記 1
0.6 *2 = 1.2 記 1
0.2 *2 = 0.4 記 0
0.4 *2 = 0.8 記 0
https://tw.answers.yahoo.com/question/index?qid=20110924000015KK00049

問題2
BYTE=4,32bit 2的31位元,算起來是2147483648
為什麼它的數值範圍是-3.4E38~3.4E38,不是-2147483648~2147483647?

問題3(已答,但可以再詳細推演)

DECLARE @NUMBER FLOAT =1000000000000000
SELECT @NUMBER ,@NUMBER -1,CAST(@NUMBER+1 AS DECIMAL(38,0))	
--RESULT 1E+15, 999999999999999 ,1000000000000001

如果FLOAT @NUMBER在記憶體時,已不精準,但為什麼+1後轉成DECIMAL又變精準了呢.
在記憶體和顯示或是儲存的關係是什麼?會什麼會有這樣的差異呢?
Ans:因為隱含轉換
參考 隱含數值轉換表、明確數值轉換表

問題4(已答,但可以再詳細推演)

DECLARE @NUMBER FLOAT =9876543219876543
SELECT @NUMBER ,@NUMBER +1,CAST(@NUMBER AS DECIMAL(38,0))
--RESULT 9.87654321987654E+15, 9.87654321987654E+15 ,9876543219876544 --它居然進位了.

為什麼轉成DECMIAL後,它幫忙進位了?
Ans:因為隱含轉換
參考 隱含數值轉換表、明確數值轉換表

ref
科學符號 https://zh.wikipedia.org/wiki/%E7%A7%91%E5%AD%A6%E8%AE%B0%E6%95%B0%E6%B3%95

待讀文章(謝謝fillano大大)
https://zh.wikipedia.org/wiki/IEEE_754
http://edisonx.pixnet.net/blog/post/46103946-%5B%E6%B5%AE%E9%BB%9E%E6%95%B8%5D-ieee754-,-c-c++-%E6%B5%AE%E9%BB%9E%E6%95%B8%E8%AA%A4%E5%B7%AE

https://zh.wikipedia.org/wiki/%E6%B5%AE%E7%82%B9%E6%95%B0
https://msdn.microsoft.com/zh-tw/library/hd7199ke.aspx
https://technet.microsoft.com/zh-tw/library/ms173773(v=sql.105).aspx

#fraction

圓頭人 iT邦新手 5 級 ‧ 2018-06-07 16:37:10 檢舉
儲進去(Decimal to IEEE 754 Floating Point Representation)
https://www.youtube.com/watch?v=8afbTaA-gOQ

然後再這樣被讀出來(EEE 754 Floating Point Representation to its Decimal Equivalent)
https://www.youtube.com/watch?v=LXF-wcoeT0o
圓頭人 iT邦新手 5 級 ‧ 2018-06-08 09:05:52 檢舉
int正整數和負整數,這樣save在記憶體
https://www.youtube.com/watch?v=4qH4unVtJkE

float point 小數點會被用2^-次方的方式被save,所以會有誤差.
0.3 = 0100 1100 1100 1100 1100 1100 1100 1100 1100.........

2 個回答

1
fillano
iT邦超人 1 級 ‧ 2018-02-05 10:19:32
最佳解答

先看一下這個:https://technet.microsoft.com/zh-tw/library/ms173773(v=sql.105).aspx

可以發現,float是用8個位元組來儲存,並不是4個位元組;有效位數是15。

看起來他用二進位表示float的方法並沒有完全依照IEEE 754,不過就差一位,應該還是可以參考一下維基百科上關於IEEE 754的說明:https://zh.wikipedia.org/wiki/IEEE_754

看更多先前的回應...收起先前的回應...
圓頭人 iT邦新手 5 級 ‧ 2018-02-06 18:38:42 檢舉

感謝大大提供的資訊,找到這篇文章的說明~
雖然還似懂非懂,但有比一開始還清楚了~
http://edisonx.pixnet.net/blog/post/46103946-%5B%E6%B5%AE%E9%BB%9E%E6%95%B8%5D-ieee754-,-c-c++-%E6%B5%AE%E9%BB%9E%E6%95%B8%E8%AA%A4%E5%B7%AE

圓頭人 iT邦新手 5 級 ‧ 2018-02-07 09:40:26 檢舉

1100 >1.100E3 右移3
0.11001100 1.10011E1 怎麼知道要左移呢?1.10011E-1嗎?那-1記錄在哪裡?也是記錄在指數嗎?
S正負號E指數F小數部分.

fillano iT邦超人 1 級 ‧ 2018-02-07 13:24:14 檢舉

因為左移以後,才會在1<R<10之間,這是科學記號規定的。

-1也是指數阿(1/10^n, n=1),是用同樣地方儲存的。

圓頭人 iT邦新手 5 級 ‧ 2018-02-09 09:15:39 檢舉

所以說指數的儲存區塊,也有分配一個位置是放正負號的嗎?

fillano iT邦超人 1 級 ‧ 2018-02-09 10:16:01 檢舉

不是...指數區塊只放無號整數。指數的實際數值是用一個固定偏移值算出來的。通常這個偏移值是:2^(e-1)-1,其中e為指數區塊的長度。32位元的浮點數中,這個長度通常是8,所以固定偏移值是127,指數區塊的值減去127,就是他代表的指數。

https://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html 這個分析還蠻清楚的,你輸入數字,他會幫你轉成IEEE-754格式。

WilliamHuang
iT邦研究生 1 級 ‧ 2018-02-01 20:46:51
【**此則訊息已被站方移除**】

我要發表回答

立即登入回答