decimal,float和double的区别
一直很奇怪C#的預(yù)定義數(shù)據(jù)類型中為什么加了一個(gè)decimal,有float和double不就夠了嗎?今天來挖一挖。
浮點(diǎn)型
?
| ? float | ? System.Single | ? 32-bit single-precision floating point | ? 7 | ? ±1.5 × 10?45 to ±3.4 × 1038 |
| ? double | ? System.Double | ? 64-bit double-precision floating point | ? 15/16 | ? ±5.0 × 10 ?324 to ±1.7 × 10308 |
?
如果我們?cè)诖a中寫一個(gè)12.3,編譯器會(huì)自動(dòng)認(rèn)為這個(gè)數(shù)是個(gè)double型。所以如果我們想指定12.3為float類型,那么你必須在數(shù)字后面加上F/f:
float f = 12.3F;
decimal類型
作為補(bǔ)充,decimal類型用來表示高精度的浮點(diǎn)數(shù)
?
| ? decimal | ? System.Decimal | ? 128-bit high precision decimal notation | ? 28 | ? ±1.0 × 10?28 to ±7.9 × 1028 |
?
從上表可以看出,decimal的有效位數(shù)很大,達(dá)到了28位,但是表示的數(shù)據(jù)范圍卻比float和double類型小。decimal類型并不是C#中的基礎(chǔ)類型,所以使用的時(shí)候會(huì)對(duì)計(jì)算時(shí)的性能有影響。
我們可以像如下的方式定義一個(gè)decimal類型的浮點(diǎn)數(shù):
decimal d = 12.30M;
對(duì)decimal、float、double錯(cuò)誤的認(rèn)識(shí)
?
在精確計(jì)算中使用浮點(diǎn)數(shù)是非常危險(xiǎn)的,盡管C#在浮點(diǎn)數(shù)運(yùn)算時(shí)采取了很多措施使得浮點(diǎn)數(shù)運(yùn)算的結(jié)果看起來是非常正常的。但實(shí)際上如果不清楚浮點(diǎn)數(shù)的特性而貿(mào)然使用的話,將造成非常嚴(yán)重的隱患。 ?
? ?
? 考慮下面的語句: ?
? ?
? ? ? ? ? ? ? double ? dd ? = ? 10000000000000000000000d; ?
? ? ? ? ? ? ? dd ? += ? 1; ?
? ? ? ? ? ? ? Console.WriteLine ? ( ? "{0:G50}", ? dd ? );???
????
? 輸出是什么?誰知道? ?
? 輸出是:1000000000000000000000000???
????
? 這就是浮點(diǎn)數(shù)精度損失的問題,最重要的是,在精度損失的時(shí)候,不會(huì)報(bào)告任何的錯(cuò)誤,也不會(huì)有任何的異常產(chǎn)生。 ?
? ?
? 浮點(diǎn)數(shù)的精度損失可能在很多地方出現(xiàn),例如d ? * ? g ? / ? g ? 不一定等于d,d ? / ? g ? * ? g也不一定等于d。???
????
? 還有兩個(gè)非常危險(xiǎn)的錯(cuò)誤認(rèn)識(shí)!! ?
? ?
? 1、decimal不是浮點(diǎn)型、decimal不存在精度損失。
? 下面有段程序大家可以去看看結(jié)果是什么。記住!所有的浮點(diǎn)型變量都存在精度損失的問題,而decimal是一個(gè)不折不扣的浮點(diǎn)型,不論它精度有多高,精度損失依然存在! ?
? ?
? ? ? ? ? ? ? ? ? decimal ? dd ? = ? 10000000000000000000000000000m; ?
? ? ? ? ? ? ? ? ? dd ? += ? 0.1m; ?
? ? ? ? ? ? ? ? ? Console.WriteLine ? ( ? "{0:G50}", ? dd ? );???
????
? 2、decimal所能儲(chǔ)存的數(shù)比double大,從double到decimal的類型轉(zhuǎn)換不會(huì)出現(xiàn)任何問題。
? 微軟在decimal的幫助上真的要好好反省了。實(shí)際上只有從整形到decimal的轉(zhuǎn)換才是擴(kuò)大轉(zhuǎn)換,decimal的精度比double大,但所能儲(chǔ)存的最大數(shù)卻比double要小。
?
?
?
“decimal?? 類型是適合財(cái)務(wù)和貨幣計(jì)算的?? 128?? 位數(shù)據(jù)類型。”
當(dāng)然,decimal在大多數(shù)情況下是安全的,但浮點(diǎn)數(shù)在理論上是不安全的。
至于精度誤差造成的顯示問題,則是很容易修補(bǔ)的。浮點(diǎn)數(shù)會(huì)帶來的問題以及整型能避免的問題就是一個(gè):
譬如說從A帳戶轉(zhuǎn)賬到B帳戶,經(jīng)計(jì)算得出結(jié)果是3.788888888888888元,那么我們從A帳戶扣除這么多錢,B帳戶增加這么多錢,但事實(shí)上A帳戶不一定會(huì)扣除準(zhǔn)確的數(shù)值,例如A帳戶的金額在100000000000,那么這個(gè)時(shí)候100000000000?? -?? 3.788888888888888運(yùn)算結(jié)果很有可能是99999999996.211111111111112。而這個(gè)時(shí)候B帳戶的金額為0則很有可能加上準(zhǔn)確的數(shù)值,如3.788888888888888,這樣一來,0.011111111111112元錢就會(huì)不見了,日積月累的,差額就會(huì)越來越大。
double是64位的,比single-32位精度高??
? decimal128位高精度浮點(diǎn)數(shù),常用于金融運(yùn)算,不會(huì)出現(xiàn)浮點(diǎn)數(shù)計(jì)算的誤差
,decimal?? 類型具有更高的精度和更小的范圍,這使它適合于財(cái)務(wù)和貨幣計(jì)算。
?
?
?
早上剛到辦公室,就被中試室打來電話叫去,原來軟件在測(cè)試過程中發(fā)現(xiàn)了個(gè)小問題:軟件讀出來的數(shù)據(jù)比設(shè)備LCD上顯示數(shù)據(jù)小了 0.01 。
怎么會(huì)這樣呢,數(shù)據(jù)類型我已經(jīng)用了 double 型了整個(gè)數(shù)據(jù)長(zhǎng)度也就6位,double型的數(shù)據(jù)有效數(shù)據(jù)位為7位,也夠了阿,不明白。于是回來下斷點(diǎn)跟蹤。
前面double型在算的時(shí)候,是沒問題的,數(shù)據(jù)是66.24,可是當(dāng)我把66.24 乘上100后的處理結(jié)果就不對(duì)了:66.24*100.0d = 6623.9999…91,問題就出在這里了。查了msdn,Double型的數(shù)據(jù):Double 值類型表示一個(gè)值介于 -1.79769313486232e308 和 +1.79769313486232e308 之間的雙精度 64 位數(shù)字,浮點(diǎn)數(shù)只能近似于十進(jìn)制數(shù)字,浮點(diǎn)數(shù)的精度決定了浮點(diǎn)數(shù)近似于十進(jìn)制數(shù)字的精確程度。默認(rèn)情況下,Double 值的精度是 15 個(gè)十進(jìn)制位,但內(nèi)部維護(hù)的最大精度是 17 位。所以就出現(xiàn)了乘上一百后,精度就不夠了。又由于我們?cè)谔幚頂?shù)據(jù)時(shí),是不允許四舍五入的,所以,經(jīng)過單位轉(zhuǎn)換后,軟件中最終顯示的數(shù)據(jù)為 66.23 ,比LCD上顯示的66.24 小了 0.01。
因此,這之后就想到了應(yīng)該用更高精度的 decimal 型。
?
| ? 類型 | ? 大致范圍 | ? 精度 | ? .NET Framework 類型 |
| ? decimal | ? ±1.0 × 10e?28 至 ±7.9 × 10e28 | ? 28 到 29 位有效位 | ? System.Decimal |
?
s在聲明decimal類型數(shù)據(jù)時(shí),可以 a: decimal myData = 100,此時(shí)編譯器隱式轉(zhuǎn)換整型數(shù)100為 100.0m;當(dāng)然也可以b: decimal myData = 100.0m,但是 如果是 decimal myData = 100.0d或者decimal myData = 100.0f,就不行了,因?yàn)?00.0d或者100.0f,編譯器認(rèn)為是浮點(diǎn)數(shù),而浮點(diǎn)數(shù)和decimal 類型之間不存在隱式轉(zhuǎn)換;因此,必須使用強(qiáng)制轉(zhuǎn)換在這兩種類型之間進(jìn)行轉(zhuǎn)換。This is the important,否則編譯器便報(bào)錯(cuò)。所以一般的財(cái)務(wù)軟件在處理時(shí),都會(huì)用decimal 類型。
好了,改用decimal 型之后,就OK 了,結(jié)果就完完整整地顯示為 66.24 了。
?
源自http://lj.soft.blog.163.com/blog/static/79402481201032210173381/轉(zhuǎn)載于:https://www.cnblogs.com/Nina-piaoye/archive/2013/05/31/3110184.html
總結(jié)
以上是生活随笔為你收集整理的decimal,float和double的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于input type=file 限制
- 下一篇: Oracle命令--alter 操作