国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

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

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 因BigDecimal類型數(shù)據(jù)引出的問題詳析

因BigDecimal類型數(shù)據(jù)引出的問題詳析

2021-05-26 13:30lensar Java教程

Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數(shù)進行精確的運算,下面這篇文章主要給大家介紹了因BigDecimal類型數(shù)據(jù)引出的問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下

前言

我們都知道,java中對大小數(shù),高精度的計算都會用到bigdecimal.但是在實際應(yīng)用中,運用bigdecimal還是會遇到一些問題,下面話不多說了,來一起看看詳細的介紹吧

問題描述:

程序中需要判斷一個字段是否為0(字段類型為bigdecimal),想都沒想,對象的判斷用equals?結(jié)果卻與預(yù)期有一定的差距,看下面代碼及運行結(jié)果。

?
1
2
3
4
5
public static void main(string[] args) {
 bigdecimal decimal1 = bigdecimal.valueof(0);
 bigdecimal decimal2 = new bigdecimal("0.00");
 system.out.println("the result is " +decimal1.equals(decimal2));
}

運行結(jié)果:

the result is false

結(jié)論: bigdecimal類型比較相等不能簡單的通過equals方法實現(xiàn)。

bigdecimal類的equals方法源碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public boolean equals(object x) {
 if (!(x instanceof bigdecimal))
  return false;
 bigdecimal xdec = (bigdecimal) x;
 if (x == this)
  return true;
 if (scale != xdec.scale)//這里會比較數(shù)字的精度
  return false;
 long s = this.intcompact;
 long xs = xdec.intcompact;
 if (s != inflated) {
  if (xs == inflated)
   xs = compactvalfor(xdec.intval);
  return xs == s;
 } else if (xs != inflated)
  return xs == compactvalfor(this.intval);
 
 return this.inflate().equals(xdec.inflate());
}

看上面的注釋可以知道,bigdecimal類的equals方法會判斷數(shù)字的精度,看下面的代碼及運行結(jié)果:

?
1
2
3
4
5
public static void main(string[] args) {
 bigdecimal decimal1 = bigdecimal.valueof(0).setscale(2);
 bigdecimal decimal2 = new bigdecimal("0.00").setscale(2);
 system.out.println("the result is " +decimal1.equals(decimal2));
}

運行結(jié)果:

the result is true

結(jié)論: 使用bigdecimal類equals方法判斷兩個bigdecimal類型的數(shù)據(jù)時,需要設(shè)置精度,否則結(jié)果可能不正確。

思考:每次都設(shè)置精度比較麻煩,有其他方式進行相等的比較嗎?

看了下bigdecimal的方法列表,有一個名為compareto的方法,通過注釋可知,貌似可以進行不同精度的比較,看下面的代碼。

?
1
2
3
4
5
public static void main(string[] args) {
 bigdecimal decimal1 = bigdecimal.valueof(1.1);
 bigdecimal decimal2 = new bigdecimal("1.10");
 system.out.println("the result is " +decimal1.compareto(decimal2));
}

運行結(jié)果:

the result is 0

0表示兩個數(shù)相等,所有可以通過compareto實現(xiàn)不同精度的兩個bigdecimal類型的數(shù)字是否相等的比較

引出的問題:公司的項目中,為了避免由于精度丟失引起問題,凡是有精度要求的字段用的都是bigdecimal類型。數(shù)據(jù)持久層用的是mybatis框架,mybatis的mapper文件中有些條件判斷用的是bigdecimal對應(yīng)的字段,如下:

?
1
2
3
4
5
6
<select id="selectbycondition" resulttype="com.scove.demo.domain.score">
 select * from tb_score where 1=1
 <if test="score!=null and score!=0">
  and score>#{score}
 </if>
 ...

score是一個bigdecimal類型的字段,score!=0 mybatis是如何進行判斷的,會不會用的是上面的equals方法?如果是那么項目上線會不會捅大簍子,想到這兒,有點怕了。寫了個程序測了下,這樣寫完全沒問題,能夠達到我想要的目的。但是還是有點擔心,看看mybatis底層是如何實現(xiàn)的吧,以免以后犯類似的錯誤嘛。

經(jīng)過分析調(diào)試,很快就找到了關(guān)鍵代碼的位置,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class expressionevaluator {
 
 public boolean evaluateboolean(string expression, object parameterobject) {
 object value = ognlcache.getvalue(expression, parameterobject);
 if (value instanceof boolean) {
  return (boolean) value;
 }
 if (value instanceof number) {
  return !new bigdecimal(string.valueof(value)).equals(bigdecimal.zero);
 }
 return value != null;
 }
...
?
1
2
3
4
5
6
7
8
9
10
11
public final class ognlcache {
 
....
 public static object getvalue(string expression, object root) {
 try {
  map<object, ognlclassresolver> context = ognl.createdefaultcontext(root, new ognlclassresolver());
  return ognl.getvalue(parseexpression(expression), context, root);
 } catch (ognlexception e) {
  throw new builderexception("error evaluating expression '" + expression + "'. cause: " + e, e);
 }
 }

用的是表達式求值,ognl這個類的竟然沒有源碼,apache的官網(wǎng)上找了下,是有相應(yīng)的源碼的,只是需要單獨下載,真麻煩,算了不看了。據(jù)說底層用的是spring 的ognl表達式,我也不 關(guān)心了。但是以后如果不確定mapper中的test是否正確咋個辦?

想了下,還是寫一個工具類在拿不準的時候用一下吧,反正拿不準的時候肯定很少,所以隨便寫了簡單的吧,如下:

?
1
2
3
4
5
6
7
8
public static void main(string[] args) {
 expressionevaluator evaluator = new expressionevaluator();
 string expression = "score!=null and score!=0";
 dynamiccontext context = new dynamiccontext(new configuration(), null);
 context.bind("score", bigdecimal.valueof(0.1));
 boolean flag = evaluator.evaluateboolean(expression , context.getbindings());
 system.out.println("the result is " +flag);
}

運行結(jié)果:

the result is true

總結(jié)

開發(fā)過程中,一定要細心去處理細節(jié)上的東西,不然一不小心就跳坑里了,輕則系統(tǒng)造成數(shù)據(jù)的不一致,修復(fù)數(shù)據(jù);重則造成重大的損失....

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:https://www.cnblogs.com/falco/p/9500833.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 毛片a级毛片免费 | 一区二区三区在线播放 | 国产在线不卡 | 日本三级一区二区 | 成人在线视频网址 | 亚洲精选一区二区 | 色综合色综合网色综合 | 亚洲视频一区二区三区 | 欧美日韩综合 | 日韩精品在线观看中文字幕 | 大尺度av在线| 波多野结衣一区二区三区中文字幕 | 国产精品久久久久久久 | 国产在线精品一区二区 | 亚洲国产综合在线观看 | 日本中文一区二区 | 人成网址| 欧美在线不卡视频 | 午夜寂寞少妇aaa片毛片 | 国产日产久久高清欧美一区 | 中文字幕高清视频 | 国产精品一区二区三 | 日韩中文字幕视频在线观看 | 91视频观看| 精品久久久久久久久久久久久久久久久久久 | 国产高清在线a视频大全 | 国产精品女教师av久久 | 综合久久综合久久 | 亚洲一区二区 | 自拍在线 | 精品久久99 | 精品在线一区二区三区 | 成人精品视频 | 久久精品国产99国产 | 久久久久久久国产精品免费播放 | 在线观看av网站 | 国产亚洲精品美女久久久久久久久久 | 久久精品国产v日韩v亚洲 | 欧洲亚洲一区 | 亚洲不卡| 日本精品在线播放 |