程序中兩個(gè)Double類型相加出現(xiàn)誤差的解決辦法
今天在自己做的系統(tǒng)中,發(fā)現(xiàn)了一個(gè)奇怪的現(xiàn)象:幾個(gè)Double類型的數(shù)據(jù)相加,到最后得出的金額比正確數(shù)值總是少了幾毛錢。以為是程序里的計(jì)算方法有問題,可是排查了很多地方,始終沒有找到問題出在哪里。最后干脆把計(jì)算方法一句一句拆分,得到了最后最簡單的一步,就是把兩個(gè)具體的數(shù)值相加,但是最后的結(jié)果居然還是錯(cuò)誤的。比如,現(xiàn)在已經(jīng)到了最簡單的一步:
double n = 171.6;
double m = 28.17;
double k = n + m;
按理說k的值應(yīng)該是199.77,但其實(shí)得到的居然是199.76999999999998。
我們的系統(tǒng)里有保留小數(shù)位數(shù)為4位,按理是可以四舍五入成199.77的。但是因?yàn)橛凶鼋痤~的合計(jì),是幾十甚至幾百個(gè)數(shù)據(jù)的相加,由于每兩個(gè)數(shù)相加的時(shí)候都可能產(chǎn)生上述誤差,因此最后得到的結(jié)果已經(jīng)有了近0.7的誤差,就算再四舍五入也于事無補(bǔ)了。
上網(wǎng)查了一下相關(guān)資料,覺得CSDN論壇里的這個(gè)帖子的解釋還是比較詳細(xì)的:http://bbs.csdn.net/topics/300023952,大意是說由于運(yùn)算的時(shí)候進(jìn)行了進(jìn)制的轉(zhuǎn)換造成的(見8樓回復(fù)),所有的精度類型在幾乎所有語言下都有這個(gè)問題。比較有效的解決辦法是使用BigDecimal(見14樓回復(fù)),但是我個(gè)人認(rèn)為那個(gè)BigDecimal的解決辦法太麻煩了,至少對于我的系統(tǒng)來說是這樣。還不如每加一次之后都進(jìn)行一次字符串轉(zhuǎn)換,保留有效的小數(shù)位數(shù),比如,上述語句可以改寫成:
double n = 171.6;
double m = 28.17;
//double k = n + m;
String kn = (n + m).ToString("N4"); //保留4位小數(shù)
double k = Convert.ToDouble(kn);
也就是說,在String kn這一步,就已經(jīng)把誤差調(diào)整好了,得到的k值就是正確的了。這樣每次相加都處理一下誤差,無論要算多少個(gè)數(shù)據(jù)的合計(jì)也不用擔(dān)心會(huì)出現(xiàn)誤差過大的情況了。
當(dāng)然最好是把這種處理方法做成一個(gè)公用方法,專門用來處理兩個(gè)數(shù)的相加。
相關(guān)文章
C# WindowsForm程序同時(shí)啟動(dòng)多個(gè)窗口類
這篇文章主要為大家詳細(xì)介紹了C# WindowsForm程序同時(shí)啟動(dòng)多個(gè)窗口類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06C#使用dir命令實(shí)現(xiàn)文件搜索功能示例
這篇文章主要介紹了C#使用dir命令實(shí)現(xiàn)文件搜索功能,結(jié)合具體實(shí)例形式分析了C#調(diào)用與使用cmd命令相關(guān)操作技巧,需要的朋友可以參考下2017-07-07BootStrap mvcpager分頁樣式(get請求,刷新頁面)
這篇文章主要介紹了BootStrap mvcpager分頁樣式(get請求,刷新頁面)的相關(guān)資料,通過引入相關(guān)文件,實(shí)現(xiàn)此功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08結(jié)合Visual C#開發(fā)環(huán)境講解C#中事件的訂閱和取消訂閱
這篇文章主要介紹了C#中事件的訂閱和取消訂閱,結(jié)合Visual C#開發(fā)環(huán)境來進(jìn)行講解,Visual C#被集成在微軟的IDE程序Visual Studio中,需要的朋友可以參考下2016-01-01C#使用隊(duì)列(Queue)解決簡單的并發(fā)問題
這篇文章主要介紹了使用隊(duì)列(Queue)解決簡單的并發(fā)問題,講解的很細(xì)致,喜歡的朋友們可以了解一下2015-07-07C# lambda表達(dá)式應(yīng)用如何找出元素在list中的索引
這篇文章主要介紹了C# lambda表達(dá)式應(yīng)用如何找出元素在list中的索引的相關(guān)資料,需要的朋友可以參考下2018-01-01Unity技術(shù)手冊之Toggle切換使用實(shí)例
這篇文章主要為大家介紹了Unity技術(shù)手冊之Toggle切換使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11C#的Process類調(diào)用第三方插件實(shí)現(xiàn)PDF文件轉(zhuǎn)SWF文件
本篇文章主要介紹了C#的Process類調(diào)用第三方插件實(shí)現(xiàn)PDF文件轉(zhuǎn)SWF文件,現(xiàn)在分享給大家,具有一定的參考價(jià)值,有需要的可以了解一下。2016-11-11