天天看點

【MaxCompute學習】隐式轉化的問題

有一次計算一個資料的百分比,想把小數結果取2位,并拼接一個百分号展示在結果報表中。用到的sql如下

很奇怪局部資料并沒有保留2位小數,比如上面的資料傳回的是67.99999999999999

我計算了下上面的結果大概得到的資料為0.0068

由于計算值采用了concat函數,concat的多個參數為string類型,如果輸入為bigint,decimal,double,datetime類型會隐式轉化為string類型,并且傳回的為string類型

也就是說有兩種情況

1.round函數傳回的數字cast為string後就丢失了精度。 2.round函數傳回的數字就丢失了精度。

上面的結果說明是round函數傳回的數字就丢失了精度。

round函數是用來計算指定到小數點位數的四舍五入的值的,如果其第一個參數為double類型,那麼函數計算的結果就是double類型,如果其第一個參數為decimal類型,那麼函數計算的結果就是decimal類型的,如果其第一個參數為string類型或者bigint類型,那麼就會隐式轉化為double類型。

單獨計算round的傳回值如下,說明double類型的round傳回值為double

再計算乘法的結果,double和bigint相計算的時候也是會發生隐式轉化的

對于操作符号的運算,string,bigint和double都可以參與算術運算,string類型會轉成double類型計算 當bigint和bigint進行除法運算的時候結果會傳回double類型,當bigint和double共同計算的時候,big今天會轉成doule類型,并且傳回結果為double類型,

那麼100變成了double類型,這時候問題就有點眉目了

double浮點數運算的時候會有丢失精度的問題,這個是所有的浮點數運算的通病,我們可以再java下驗證一下

當然這個問題的最終解決方案很簡單,不過以後再計算對精度要求比較高的資料的時候建議還是設計成decimal類型

select round(10230*100/1497409,4) from  dual;

文章轉載自wangming

歡迎加入“數加·maxcompute購買咨詢”釘釘群(群号: 11782920)進行咨詢,群二維碼如下:

【MaxCompute學習】隐式轉化的問題

繼續閱讀