Board logo

Subject: SQL里面Float,Money、Decimal [Print This Page]

Author: jAmEs_    Time: 2007-5-31 15:32     Subject: SQL里面Float,Money、Decimal

以前浮點的近似值問題一直困擾著我,后來我知道Decimal可以表示精確的浮點,而Float近似值表示法會代“尾巴”,開始以為問題解決了,今天我發現錯了。。。
測試建立一個表:
create table floattest
(
   dec_col dec(10,1),
   money_col smallmoney,
   float_col float,
)
通過程序插入一些記錄,我通過RoundTo函數把浮點處理剩下1位小數。增加幾條記錄后,我再重新打開這個表,我以為
FieldByName('dec_col').AsFloat = RoundTo(FieldByName('dec_col').AsFloat, -1)
結果錯了,不等的。
而竟然:
FieldByName('float_col').AsFloat = RoundTo(FieldByName('float_col').AsFloat, -1)
網上資料不是說Decimal可以表示精確的值嗎?怎么不行呢?有沒有人知道怎么回事?
Author: skyjacker    Time: 2007-5-31 16:27

"Decimal可以表示精確的浮點"是指定点浮点数。
浮点数本身就不是精确的。
Delphi 能表示 18 位浮点数小数, 超了要用科学计数法。

Decimal 是 9 个字节,
Float 是 8 个字节。
FieldByName('dec_col').AsFloat 将定点浮点数 Decimal 转为 FLoat 时,会损失一个字节的精度。

你的浮点数比较 FieldByName('dec_col').AsFloat = RoundTo(FieldByName('dec_col').AsFloat, -1), 不能这样比较阿
Author: jAmEs_    Time: 2007-5-31 17:05

我剛才找了些資料,其實應該是因為AsFloat又把精確的值變成近似值。也就是,雖然SQL里面有Dec這樣的精確類型,但是Delphi卻沒有對于的類型。

至於你說的:
Decimal 是 9 个字节,
Float 是 8 个字节。
FieldByName('dec_col').AsFloat 将定点浮点数 Decimal 转为 FLoat 时,会损失一个字节的精度。
好像不是這樣吧。。。其實我用DEC(5,1),DEC就編程5字節了。然后再測試,還是不會得出精確的數值。

其實是我之前理解錯誤了一個地方,我當時認為RoundTo以后就是精確的,其實,RoundTo以后,它依然是浮點,也是不精確的。。。

總之,浮點就是不適宜用<>和=來比較。

不過,為何double就是不能表達精確的東東呢。。。也就是RoundTo以后,為何它還要保留“尾巴”,難道這個是CPU的浮點計算一定要這樣?哪怕是
d := 2.1;
這樣的運算,也會給帶上“尾巴”。
Author: jAmEs_    Time: 2007-5-31 17:55

說實在,除不盡的時候,帶“尾巴”也正常,但是除的盡也帶,實在是覺得奇怪,為何要這樣?哪位高人指點一下~~




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0