一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫(kù)技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫(kù) - Mysql - MySQL中ROUND函數(shù)進(jìn)行四舍五入操作陷阱分析

MySQL中ROUND函數(shù)進(jìn)行四舍五入操作陷阱分析

2019-07-08 11:36Joker_Ye Mysql

這篇文章主要介紹了MySQL中ROUND函數(shù)進(jìn)行四舍五入操作陷阱,結(jié)合實(shí)例形式分析了mysql使用ROUND函數(shù)進(jìn)行四舍五入運(yùn)算中出現(xiàn)的問題及其錯(cuò)誤原因,需要的朋友可以參考下

本文實(shí)例講述了MySQL中ROUND函數(shù)進(jìn)行四舍五入操作陷阱。分享給大家供大家參考,具體如下:

在MySQL中, ROUND 函數(shù)用于對(duì)查詢結(jié)果進(jìn)行四舍五入,不過最近使用ROUND函數(shù)四舍五入時(shí)意外發(fā)現(xiàn)并沒有預(yù)期的那樣,本文將這一問題記錄下來(lái),以免大家跟我一樣犯同樣的錯(cuò)誤。

問題描述

假如我們有如下一個(gè)數(shù)據(jù)表 test ,建表語(yǔ)句如下

CREATE TABLE test (
 id int(11) NOT NULL AUTO_INCREMENT,
 field1 bigint(10) DEFAULT NULL,
 field2 decimal(10,0) DEFAULT NULL,
 field3 int(10) DEFAULT NULL,
 field4 float(15,4) DEFAULT NULL,
 field5 float(15,4) DEFAULT NULL,
 field6 float(15,4) DEFAULT NULL,
 PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我們創(chuàng)建了一個(gè)名為 test 的表,出了 id 字段之外還包含了多個(gè)字段,擁有這不同的數(shù)據(jù)類型。我們向這個(gè)表中插入一條數(shù)據(jù)

INSERT INTO test (field1, field2, field3, field4, field5, field6) VALUE (100, 100, 100, 1.005, 3.5, 2.5);

插入之后表中的數(shù)據(jù)是這樣的

mysql> select * from test;
+----+--------+--------+--------+--------+--------+--------+
| id | field1 | field2 | field3 | field4 | field5 | field6 |
+----+--------+--------+--------+--------+--------+--------+
| 1 |  100 |  100 |  100 | 1.0050 | 3.5000 | 2.5000 |
+----+--------+--------+--------+--------+--------+--------+
1 rowin set (0.00 sec)

如果現(xiàn)在我們執(zhí)行下面這個(gè)SQL,你覺得結(jié)果會(huì)是什么樣的呢?

SELECT
 round(field1 * field4),
 round(field2 * field4),
 round(field3 * field4),
 round(field1 * 1.005),
 round(field2 * 1.005),
 round(field3 * 1.005),
 round(field5),
 round(field6)
FROM test;

最初一直以為這樣的結(jié)果肯定是都是 101 ,因?yàn)樯厦孢@六個(gè)取值結(jié)果都是對(duì) 100 * 1.005 進(jìn)行四舍五入,結(jié)果肯定都是 101 才對(duì),而后面兩個(gè)肯定是 4 和 3 才對(duì),但是最終的結(jié)果卻是與設(shè)想的大相徑庭

*************************** 1. row ***************************
round(field1 * field4): 100
round(field2 * field4): 100
round(field3 * field4): 100
 round(field1 * 1.005): 101
 round(field2 * 1.005): 101
 round(field3 * 1.005): 101
    round(field5): 4
    round(field6): 2
1 rowin set (0.00 sec)

為什么會(huì)這樣?

同樣是100*1.005,為什么從數(shù)據(jù)庫(kù)中的字段相乘得到的結(jié)果和直接字段與小數(shù)相乘得到的不一樣呢?

對(duì)這個(gè)問題百思不得其解,各種百度谷歌無(wú)果。。。沒辦法,還得靠自己,這個(gè)時(shí)候最有用的就是官網(wǎng)文檔了,于是查詢了mysql官方文檔中關(guān)于ROUND函數(shù)的部分,其中包含下面兩條規(guī)則

  • For exact-value numbers, ROUND() uses the “round half up” rule對(duì)于精確的數(shù)值, ROUND 函數(shù)使用四舍五入
  • For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the “round to nearest even” rule: A value with any fractional part is rounded to the nearest even integer. (對(duì)于近似值,則依賴于底層的C函數(shù)庫(kù),在很多系統(tǒng)中 ROUND 函數(shù)會(huì)使用“取最近的偶數(shù)”的規(guī)則)

通過這兩條規(guī)則,我們可以看出,由于我們?cè)谑褂脙蓚€(gè)字段相乘的時(shí)候,最終的結(jié)果是按照 float 類型處理的,而在計(jì)算機(jī)中 float 類型不是精確的數(shù),因此處理結(jié)果會(huì)按照第二條來(lái),而直接整數(shù)字段與1.005這樣的小數(shù)運(yùn)算的結(jié)果是因?yàn)閮蓚€(gè)參與運(yùn)算的值都是精確數(shù),因此按照第一條規(guī)則計(jì)算。從 field5 和 field6 執(zhí)行 ROUND 函數(shù)的結(jié)果可以明確的看確實(shí)是轉(zhuǎn)換為了最近的偶數(shù)。

總結(jié)

從這個(gè)例子中可以看到,在MySQL中使用ROUND還是要非常需要注意的,特別是當(dāng)參與計(jì)算的字段中包含浮點(diǎn)數(shù)的時(shí)候,這個(gè)時(shí)候計(jì)算結(jié)果是不準(zhǔn)確的。

希望本文所述對(duì)大家MySQL數(shù)據(jù)庫(kù)計(jì)有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美操屁股 | 双性太子 | 亚洲第6页 | 国产一区二区免费在线 | 国产精品99久久免费观看 | 五月天国产视频 | 日本一区二区视频在线 | 大伊香蕉精品视频一区 | 日韩成人精品在线 | 亚洲色图亚洲色图 | 欧美精品亚洲精品日韩专区va | 女性性色生活片免费观看 | 姐姐不~不可以动漫在线观看 | 欧美日韩中文字幕在线视频 | 明星乱淫 | 亚洲国产精品久久久久久 | 美女被上漫画 | 扒开双腿疯狂进出爽爽动态图 | 99热这里只有精品一区二区三区 | 欧美操大逼视频 | 男人狂擦女人的下面视频 | yy6080久久国产伦理 | 母爱成瘾在线观看 | 国产v日韩v欧美v精品专区 | piss美女厕所小便 | 亚洲看片lutube在线入口 | 国产一页| 免费看伦理片 | 亚洲成人aa | 国产免费资源高清小视频在线观看 | 福利片成人午夜在线 | 亚洲视频99 | 日本红色高清免费观看 | 第一次做m被调教经历 | 国产 国语对白 露脸正在播放 | 天堂在线观看中文字幕 | 免费国产高清精品一区在线 | 欧美日韩一区二区三在线 | 古装一级毛片 | 双性肉文高h | 日韩一区二区三区四区区区 |