mysql 設定double列累加,導致精確缺失

2022-06-27 20:24:14 字數 2533 閱讀 9779

最近做工廠專案,測試提的乙個bug在本地測了好久一直沒復現;直接連測試線的資料庫,又經過一系列流程模擬最終在本地復現了這個問題;由於有訊息日誌的定時輸出,只能打點介入來追蹤bug,最後發現問題出在對double列累加的sql語句上,真是一頓好找。

由此,我根據本地已復現的bug做了如下測試;

新建一張表:

create table `test` (

`id`

int(11) not null auto_increment comment '

主鍵id',

`numdouble`

double not null comment '

double型別取值',

`numdoublelimit`

double default null comment '

double型別精確取值',

`numdecimal`

decimal(10,5) not null comment '

decimal精確取值',

primary key (`id`)

) engine=innodb auto_increment=2 default charset=utf8;

先插入一條資料:

insert into `jc_x1web`.`test` (`id`, `numdouble`, `numdoublelimit`, `numdecimal`) values ('

1', '

0', '

0', '

0.00000

');

執行以下sql三次:

# double列累加

update test set numdouble = numdouble + 192.2 where id = 1

;# double列取約數後累加,double型別會在0後的剩餘長度補足一些小數,而大概就是這些小數導致的double型別求和後精度缺失

update test set numdoublelimit = round(numdoublelimit + 192.2, 5) where id = 1

;# decimal列累加

update test set numdecimal = numdecimal + 192.2 where id = 1

;select numdouble,numdoublelimit,numdecimal from test;

發現結果如下:

解決方案:

double列取約數後再累加求和,問題解決!
由此,總結如下:

1

、追查日誌,在大專案中由於定時器任務等複雜業務,會導致列印大量的日誌,如果沒有關鍵日誌就會很難追蹤bug;

2、開發完的專案在測試線總會出現一些奇奇怪怪的問題,最好可以直接連測試環境直接復現問題,然後再逐一排除問題;

3、找到問題的前後邏輯,並聯絡'

上下文'

,有利於確認問題位置、確定問題處理方案;

4、設計表的小數字段型別時,形如金額、收貨數量等要求精度的屬性時可以用decimal;如果擔心decimal型別的列取值問題,也可以使用double型別,但是最好不要用sql直接累加double列,建議在外層**計算好double列值,sql語句僅set儲存double列的值

***中的double列求和精度缺失,請參考:

double a = 192.2d

;double b =0d;

b +=a;

b +=a;

b +=a;

system.

out.println(b);//

結果:576.5999999999999

bigdecimal adecimal = new bigdecimal(double.tostring(192.2d

));bigdecimal bdecimal = new

bigdecimal(double.tostring(0d));

bdecimal =bdecimal.add(adecimal).add(adecimal).add(adecimal);

system.

out.println(bdecimal.doublevalue());//

結果:576.6

補充示例:

double a = 0.21

;double b = 0.0

;double c = 0.11

;

double d = a - b -c;

system.

out.println(d);//

0.09999999999999999

double e = 0.21 - 0 - 0.11

;system.

out.println(e);//

0.09999999999999999

mysql列鍵 Mysql列屬性

列屬性又稱之為字段屬性 在mysql中一共有6個屬性 null,預設值 default 列描述 comment 主鍵 primary key 唯一鍵 unique key 和自動增長 修改資料庫字符集 字符集和校對集 alter database 資料庫名字 charset 字符集 null屬性 1...

mysql偽列 MySQL使用偽列

在查詢資料庫的時候,我們有時候需要對查詢出來的資料加上序列,1,2,3,n 例如 我們根據表的某個字段排序後,要對這些資料加上序列,這個時候序號常常不是我們建表時設定好的自增的主鍵id,怎麼辦呢?可能我們會用變數來解決,如下 set rownum 0 select rownum rownum 1 a...

mysql列連線 mysql 多列連線

1 concat 函式 1.1 mysql的concat函式可以連線乙個或者多個字串,如 mysql select concat 10 concat 10 10 1 row in set 0.00 sec mysql select concat 11 22 33 concat 11 22 33 11...