最近公司要做各種報表統計,剛開始,我很愉快的提交了代碼,沒想到第二天前端告訴我說精度丟失,當時我就覺得納悶,怎麼會呢?
我剛開始代碼大概是這樣寫的:結果本來應該是 11.4,但真正輸出的結果卻是:11.399999999999999
@Test
public void test() {
List<Double> list = Arrays.asList(4.3, 4.8, 2.3);
double value = list.stream().map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add).doubleValue();
System.out.println(value);
}
然後我通過peek發現了問題:
@Test
public void test(){
List<Double> list = Arrays.asList(4.3, 4.8, 2.3);
double value = list.stream().peek(e -> System.out.println("from stream " + e)).map(BigDecimal::new)
.peek(e -> System.out.println("from map " + e)).reduce(BigDecimal.ZERO, BigDecimal::add).doubleValue();
System.out.println(value);
}
/* from stream 4.3
from map 4.29999999999999982236431605997495353221893310546875
from stream 4.8
from map 4.79999999999999982236431605997495353221893310546875
from stream 2.3
from map 2.29999999999999982236431605997495353221893310546875
11.399999999999999*/
最後只好先轉字符串問題解決:
@Test
public void test(){
List<Double> list = Arrays.asList(4.3, 4.8, 2.3);
double value = list.stream().peek(e -> System.out.println("from stream " + e)).map(String::valueOf).peek(e -> System.out.println("from String " + e)).map(BigDecimal::new)
.peek(e -> System.out.println("from map " + e)).reduce(BigDecimal.ZERO, BigDecimal::add).doubleValue();
System.out.println(value);
}
/*
from stream 4.3
from String 4.3
from map 4.3
from stream 4.8
from String 4.8
from map 4.8
from stream 2.3
from String 2.3
from map 2.3
11.4*/
以上代碼如果在工作中建議轉字符串前先加上 filter(Objects::nonNull) 避免後面報 NumberFormatException 該異常影響程序結果
工作一段時間感覺對於積極做好相關筆記非常非常重要,因爲很多東西自己即使學過,但是一段時間不用,真的很容易忘記。有時在公司我直接在知乎或者我的其他博客網站搜我的賬號,然後看自己寫的筆記。
好記性不如爛筆頭 ----- ----------- 以後時刻謹記