自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

公司同事用 Float 和 Double ,結(jié)果導(dǎo)致..

運(yùn)維 數(shù)據(jù)庫(kù)運(yùn)維
BigDecimal 阿粉相信大家對(duì)這個(gè)肯定不陌生,只要你公司的業(yè)務(wù)中涉及到一些比較精確的數(shù)字的時(shí)候,都會(huì)使用 BigDecimal,而不會(huì)去使用 Float 和 double,并且在數(shù)據(jù)庫(kù)做設(shè)計(jì)的時(shí)候,如果是小數(shù)類型,也是會(huì)讓你使用 BigDecimal 而不是 float 和 double。

[[434238]]

BigDecimal 阿粉相信大家對(duì)這個(gè)肯定不陌生,只要你公司的業(yè)務(wù)中涉及到一些比較精確的數(shù)字的時(shí)候,都會(huì)使用 BigDecimal,而不會(huì)去使用 Float 和 double,并且在數(shù)據(jù)庫(kù)做設(shè)計(jì)的時(shí)候,如果是小數(shù)類型,也是會(huì)讓你使用 BigDecimal 而不是 float 和 double。為什么呢?阿粉來(lái)解釋一下。

float和double

float 單精度浮點(diǎn)數(shù)在機(jī)內(nèi)占 4 個(gè)字節(jié),用 32 位二進(jìn)制描述

double 雙精度浮點(diǎn)數(shù)在機(jī)內(nèi)占 8 個(gè)字節(jié),用 64 位二進(jìn)制描述

注意float型定義的數(shù)據(jù)末尾必須有"f"或"F",為了和double區(qū)別

我們來(lái)寫(xiě)一段簡(jiǎn)單的程序來(lái)實(shí)驗(yàn)一下為什么它不行

  1. System.out.println(2.0-1.4); 

如果是有經(jīng)驗(yàn)的開(kāi)發(fā)人員,肯定覺(jué)得這么寫(xiě)出來(lái)是不是有問(wèn)題?這直接減法減出來(lái)的數(shù)據(jù)應(yīng)該不對(duì),是的,結(jié)果肯定不對(duì)。

  1. 0.6000000000000001 

為什么運(yùn)算結(jié)果有問(wèn)題呢?那加法和乘法是不是都會(huì)有這種問(wèn)題,恭喜你,想到了,確實(shí)會(huì)有這種問(wèn)題,而這個(gè)問(wèn)題,就得從我們的計(jì)算機(jī)去開(kāi)始討論了,計(jì)算機(jī)并不能識(shí)別除了二進(jìn)制數(shù)據(jù)以外的任何數(shù)據(jù)。也就是說(shuō),我們傳遞給計(jì)算機(jī)的是十進(jìn)制的數(shù)據(jù),但是計(jì)算機(jī)需要先把我們給的數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制的數(shù)據(jù),因?yàn)椴荒苤苯幼R(shí)別十進(jìn)制的數(shù)據(jù),這時(shí)候,2.0 是十進(jìn)制的數(shù)據(jù),轉(zhuǎn)換成二進(jìn)制的數(shù)據(jù),而1.4呢?轉(zhuǎn)換成二進(jìn)制的數(shù)據(jù)反而出現(xiàn)了問(wèn)題 1.4在二進(jìn)制中,則是會(huì)出現(xiàn)1.399999。。。這樣的數(shù)據(jù),當(dāng)我們進(jìn)行數(shù)據(jù)轉(zhuǎn)換的時(shí)候,就出現(xiàn)了2.0-1.399999這樣的數(shù)據(jù)。

這個(gè)時(shí)候就有人問(wèn)了,我定義 float 類型為 1.4 的時(shí)候?yàn)槭裁床皇? 1.399999999呢?這就是不進(jìn)行浮點(diǎn)計(jì)算的時(shí)候,在十進(jìn)制里浮點(diǎn)數(shù)能正確顯示。也就是說(shuō),你如果知識(shí)定義了類型為 float 的話,但是你不用這個(gè)數(shù)字去進(jìn)行計(jì)算,那就沒(méi)問(wèn)題,但是一旦參與了運(yùn)算,那就不行了,分分鐘被diss。

阿里手冊(cè)定義

數(shù)據(jù)庫(kù) 小數(shù)類型為 decimal,禁止使用 float 和 double。

在存儲(chǔ)的時(shí)候,float 和 double 都存在精度損失的問(wèn)題,很可能在比較值的時(shí)候,得到不正確的 結(jié)果。如果存儲(chǔ)的數(shù)據(jù)范圍超過(guò) decimal 的范圍,建議將數(shù)據(jù)拆成整數(shù)和小數(shù)并分開(kāi)存儲(chǔ)。

Java程序:使用 BigDecimal 來(lái)定義值,再進(jìn)行浮點(diǎn)數(shù)的運(yùn)算操作

BigDecimal 是 Java 在 java.math 包中提供的API類,用來(lái)對(duì)超過(guò)16位有效位的數(shù)進(jìn)行精確的運(yùn)算

使用 BigDecimal 要注意的東西

1.BigDecimal(double) 創(chuàng)建一個(gè)具有參數(shù)所指定雙精度值的對(duì)象

但是這種類型是都不推薦使用的,為什么不推薦使用,我們來(lái)試一下

  1. BigDecimal bigDecimal = new BigDecimal(0.2); 
  2.  
  3. System.out.println(bigDecimal); 

當(dāng)你寫(xiě)出這段代碼的時(shí)候,感覺(jué)沒(méi)啥問(wèn)題,當(dāng)輸出出來(lái)的時(shí)候,就懵了。

  1. 0.200000000000000011102230246251565404236316680908203125 

又出現(xiàn)精度問(wèn)題了?其實(shí)當(dāng)你在點(diǎn)擊到這個(gè)方法看源碼的時(shí)候,注釋都提醒你慎重了。

  1. * The results of this constructor can be somewhat unpredictable.     這個(gè)構(gòu)造函數(shù)可以有些不可預(yù)測(cè)的結(jié)果 
  2. * One might assume that writing {@code new BigDecimal(0.1)} in 
  3. * Java creates a {@code BigDecimal} which is exactly equal to 
  4. * 0.1 (an unscaled value of 1, with a scale of 1), but it is 
  5. * actually equal to 
  6. * 0.1000000000000000055511151231257827021181583404541015625. 
  7. * This is because 0.1 cannot be represented exactly as a 
  8. * {@code double} (orfor that matter, as a binary fraction of 
  9. any finite length).  Thus, the value that is being passed 
  10. * <i>in</i> to the constructor is not exactly equal to 0.1, 
  11. * appearances notwithstanding. 

阿粉看到第一句話的時(shí)候,就知道,以后別用 double 數(shù)據(jù)類型去初始化這個(gè) bigDecimal 了,不靠譜呀。

也就是說(shuō)存在精度損失風(fēng)險(xiǎn),在精確計(jì)算或值比較的場(chǎng)景中可能會(huì)導(dǎo)致業(yè)務(wù)邏輯異常

既然不推薦使用 BigDecimal(double)。那么推薦使用什么呢?

BigDecimal(string) 或者使用 valueof

  1. BigDecimal bigDecimal = new BigDecimal("0.2"); 
  2. System.out.println(bigDecimal); 
  3. BigDecimal bigDecimal1 = BigDecimal.valueOf(0.2); 
  4. System.out.println(bigDecimal1); 

這時(shí)候,我們?cè)賮?lái)看看是否和我們預(yù)期的結(jié)果是一樣的。

  1. 0.2 
  2.  
  3. 0.2 

這兩個(gè)實(shí)際上都是一個(gè),valueof 只不過(guò)是在源碼中幫我們把 double 給變換成了 Double.toString(val) ,也就是還是string。

這就是為什么有些面試官在面試基礎(chǔ)的時(shí)候,很多次會(huì)問(wèn),float 和 double 都會(huì)丟失精度,BigDecimal 會(huì)丟失精度么?為什么?

你如果回答不會(huì)丟失精度,那恭喜你,你涼了,如果你回答會(huì)丟失精度,那么面試官肯定會(huì)追問(wèn)到什么情況會(huì)丟失精度,什么情況不會(huì)丟失精度。

這也是為什么在 Effective Java 和 Mysql 必會(huì)內(nèi)容 書(shū)中都會(huì)提到這塊內(nèi)容,如果你是一個(gè)幾年工作經(jīng)驗(yàn)的人,就不會(huì)有這種錯(cuò)誤,但是你初入職場(chǎng),經(jīng)驗(yàn)沒(méi)那么多,基礎(chǔ)沒(méi)那么牢固的肯定會(huì)發(fā)生這種事,趕快去檢查一下你們公司的代碼吧。

BigDecimal 的加減乘除

  • 加法:add
  • 減法:subtract
  • 乘法:multiply
  • 除法:divide

BigDecimal保留小數(shù)點(diǎn)問(wèn)題

ROUND_DOWN :向零方向舍入

ROUND_UP :向遠(yuǎn)離0的方向舍入

ROUND_CEILING:向正無(wú)窮方向舍入

ROUND_FLOOR :向負(fù)無(wú)窮方向舍入

ROUND_HALF_DOWN:相當(dāng)于五舍六入

ROUND_HALF_UP:相當(dāng)于四舍五入(經(jīng)常使用)

 

以上就是阿粉想給大家說(shuō)的關(guān)于 BigDecimal 的內(nèi)容了,你要去看看你公司的代碼么?

 

責(zé)任編輯:武曉燕 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2020-07-22 09:25:11

DockerK8S云計(jì)算

2023-12-11 08:43:31

FloatDoubleJava

2011-11-23 13:04:19

Java高精度BigDecimal

2022-06-21 11:24:05

多線程運(yùn)維

2013-03-05 10:24:51

創(chuàng)業(yè)硅谷面試官

2022-12-31 08:56:46

CIOIT

2020-10-31 09:06:37

C語(yǔ)言編程語(yǔ)言

2010-09-01 11:21:18

CSSpositionfloat

2010-09-09 15:08:40

CSSfloatclear

2020-02-22 08:02:07

春節(jié)疫情防控口罩

2024-06-21 14:13:44

2020-08-24 07:52:40

代理Java動(dòng)態(tài)

2022-12-23 08:37:16

BigDecimaljava

2011-01-20 11:42:49

同事

2018-08-24 10:16:23

內(nèi)存浮點(diǎn)數(shù)存儲(chǔ)

2010-09-02 11:18:46

CSSfloatposition

2022-09-04 12:43:03

算法裁員Meta

2010-09-13 12:56:56

CSSpositionfloat

2019-09-09 13:58:07

2010-09-16 09:05:50

CSS display
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)