日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 取 浮点运算_mysql 浮点型运算误差原因分析及解决方法

發(fā)布時(shí)間:2024/4/18 数据库 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 取 浮点运算_mysql 浮点型运算误差原因分析及解决方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在進(jìn)行金融財(cái)務(wù)等數(shù)值運(yùn)算時(shí),請使用decimal 類型,不要使用float和double類型!因?yàn)閐ecimal的精度最高

如下C#代碼:

float a = 0.65f;

float b = 0.6f;

float c = a - b;

此時(shí)c為多少?

0.05?錯(cuò)誤!

此時(shí)c為0.0499999523!

為什么?

其根本原因是計(jì)算機(jī)所使用二進(jìn)制01代碼無法準(zhǔn)確表示某些帶小數(shù)位的十進(jìn)制數(shù)據(jù)。

下面我們來分析下:

我們知道將一個(gè)十進(jìn)制數(shù)值轉(zhuǎn)換為二進(jìn)制數(shù)值,需要通過下面的計(jì)算方法:

1. 整數(shù)部分:連續(xù)用該整數(shù)除以2,取余數(shù),然后商再除以2,直到商等于0為止。然后把得到的各個(gè)余數(shù)按相反的順序排列。簡稱"除2取余法"。

2. 小數(shù)部分:十進(jìn)制小數(shù)轉(zhuǎn)換為二進(jìn)制小數(shù),采用"乘2取整,順序排列"法。用2乘以十進(jìn)制小數(shù),將得到的整數(shù)部分取出,再用2乘余下的小數(shù)部分,然后再將積的整數(shù)部分取出,如此進(jìn)行,直到積中的小數(shù)部分為0或者達(dá)到所要求的精度為止。然后把取出的整數(shù)部分按順序排列起來,即先取出的整數(shù)部分作為二進(jìn)制小數(shù)的高位,后取出的整數(shù)部分作為低位有效位。簡稱"乘2取整法"。

3. 含有小數(shù)的十進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制,整數(shù)、小數(shù)部分分別進(jìn)行轉(zhuǎn)換,然后相加。

例如:將十進(jìn)制數(shù)值25.75轉(zhuǎn)換為二進(jìn)制數(shù)值,步驟如下:

25(整數(shù)部分)

25/2=12......1

12/2=6.......0

6/2=3......0

3/2=1......1

1/2=0......1

(25) 10=(11001) 2

0.75(小數(shù)部分)

0.75*2=1.5......1

0.5*2=1......1

(0.75) 10=(0.11) 2

(25.75) 10=(11001) 2+(0.11) 2=(11001.11) 2

按照上述方法,我們將0.65及0.6轉(zhuǎn)換為二進(jìn)制代碼:

(0.65)10 = (0.101001100110011001100110011001100110011......)2

(0.6) 10 = (0.10011001100110011001100110011001100110011......)2

后面的省略號表示已經(jīng)算不完了,后面在無限重復(fù) 0011 這段二進(jìn)制數(shù)值。

文章開始部分,我們用的float類型,下面我們來看看float類型是否能存儲上面轉(zhuǎn)換出的二進(jìn)制代碼。

目前計(jì)算機(jī)上存儲浮點(diǎn)數(shù)值是按照IEEE(電氣和電子工程師協(xié)會)754浮點(diǎn)存儲格式標(biāo)準(zhǔn)來存儲的。

IEEE單精度浮點(diǎn)格式共32位,包含三個(gè)構(gòu)成字段:23位小數(shù)f,8位偏置指數(shù)e,1位符號s。將這些字段連續(xù)存放在一個(gè)32位字里,并對其進(jìn)行編碼。其中0:22位包含23位的小數(shù)f; 23:30位包含8位指數(shù)e;第31位包含符號s。如下圖所示:

也就是說上面將0.65及0.5轉(zhuǎn)換出的二進(jìn)制代碼,我們只能存儲23位,即使數(shù)據(jù)類型為double,也只能存儲52位,這樣大家便能看出問題出現(xiàn)的原因了。

截取的二進(jìn)制代碼已無法正確表示0.65及0.5,根據(jù)這個(gè)二進(jìn)制代碼肯定無法正確得到結(jié)果0.05。

如何解決這個(gè)問題?知道其根本原因后,我們知道是無法從根本上解決這個(gè)問題的,但我們可以有一些曲線救國的方法,下面列舉幾個(gè):

1. 因?yàn)槎M(jìn)制數(shù)值可以準(zhǔn)確表示整數(shù)(可以使用整數(shù)轉(zhuǎn)換為二進(jìn)制方法驗(yàn)證下),所以可以將小數(shù)乘以10或100等變成整數(shù),然后做整數(shù)運(yùn)算,最后再通過除以10或100等獲得結(jié)果;

2. 通過截取結(jié)果的有效小數(shù)位數(shù)等,來取得最好的近似結(jié)果,然后在做處理。

3. 對于可以用有限長度的二進(jìn)制數(shù)值表示的十進(jìn)制數(shù)值,可以使用存儲位數(shù)大于其長度的數(shù)據(jù)類型。

解決方案正在補(bǔ)充中……,若各位有什么好的方法也可以提出來!

以上解決方案需要按照使用的實(shí)際情況來決定使用哪種方法。

本文原創(chuàng)發(fā)布php中文網(wǎng),轉(zhuǎn)載請注明出處,感謝您的尊重!

總結(jié)

以上是生活随笔為你收集整理的mysql 取 浮点运算_mysql 浮点型运算误差原因分析及解决方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。