激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

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

服務器之家 - 編程語言 - Java教程 - Java DecimalFormat 保留小數位及四舍五入的陷阱介紹

Java DecimalFormat 保留小數位及四舍五入的陷阱介紹

2022-02-16 11:01智鼎在線IT團隊 Java教程

這篇文章主要介紹了Java DecimalFormat 保留小數位及四舍五入的陷阱,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

需求

業務需要導出的Excel的數字內容保留兩位小數,并且四舍五入

代碼實現

百度一圈所抄襲的代碼

?
1
2
DecimalFormat dfScale2 = new DecimalFormat("###.##");
dfScale2.format(1.125D);

發現問題

導出數據很詭異.不是所有數據都是如所想的四舍五入.

經過排查最終發現是RoundingMode的問題,應該使用HALF_UP,

DecimalFormat 默認使用的是HALF_EVEN

?
1
2
3
4
5
DecimalFormat dfScale2 = new DecimalFormat("###.##");
System.out.println("dfScale2.getRoundingMode()=" + dfScale2.getRoundingMode());
//輸出結果
dfScale2.getRoundingMode()=HALF_EVEN
//

RoundingMode.HALF_EVEN

想了解HALF_EVEN,去官網API看了下

HALF_EVEN 被舍位是5(如保留兩位小數的2.115),后面還有非0值進1(如保留兩位小數的2.11500001 格式化為2.12),5后面沒有數字或者都是0時,前面是偶數則舍,是奇數則進1,目標是讓被舍前一位變為偶數.

  • CEILING 向更大的值靠近
  • Rounding mode to round towards positive infinity.
  • DOWN向下取整
  • Rounding mode to round towards zero.
  • FLOOR 向更小的值靠近
  • Rounding mode to round towards negative infinity.
  • HALF_DOWN 五舍六入
  • Rounding mode to round towards “nearest neighbor” unless both neighbors are equidistant, in which case round down.
  • HALF_EVEN
  • Rounding mode to round towards the “nearest neighbor” unless both neighbors are equidistant, in which case, round towards the even neighbor.
  • HALF_UP 四舍五入
  • Rounding mode to round towards “nearest neighbor” unless both neighbors are equidistant, in which case round up.
  • UNNECESSARY 設置這個模式,對于精確值格式化會拋出異常
  • Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.
  • UP 向遠離數字0進行進位.
  • Rounding mode to round away from zero.

錯誤的代碼測試RoundingMode.HALF_EVEN

為了更好的理解HALF_EVEN,寫了些測試代碼但是發現自己更迷惘了…搞不清楚到底HALF_EVEN是什么機制進舍…輸出結果的尾數很不規律.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
public class LocalTest {
//定義一個保留兩位小數格式的 DecimalFormat 的變量 dfScale2
 @Test
  public void testDecimalFormat() {
    DecimalFormat dfScale2 = new DecimalFormat("###.##");
    System.out.println("dfScale2.getRoundingMode()=" + dfScale2.getRoundingMode());
    System.out.println("dfScale2.format(1.125D)=" + dfScale2.format(1.125D));
    System.out.println("dfScale2.format(1.135D)=" + dfScale2.format(1.135D));
    System.out.println("dfScale2.format(1.145D)=" + dfScale2.format(1.145D));
    System.out.println("dfScale2.format(1.225D)=" + dfScale2.format(1.225D));
    System.out.println("dfScale2.format(1.235D)=" + dfScale2.format(1.235D));
    System.out.println("dfScale2.format(1.245D)=" + dfScale2.format(1.245D));
    System.out.println();
    System.out.println("dfScale2.format(2.125D)=" + dfScale2.format(2.125D));
    System.out.println("dfScale2.format(2.135D)=" + dfScale2.format(2.135D));
    System.out.println("dfScale2.format(2.145D)=" + dfScale2.format(2.145D));
    System.out.println("dfScale2.format(2.225D)=" + dfScale2.format(2.225D));
    System.out.println("dfScale2.format(2.235D)=" + dfScale2.format(2.235D));
    System.out.println("dfScale2.format(2.245D)=" + dfScale2.format(2.245D));
    System.out.println();
    System.out.println("dfScale2.format(3.125D)=" + dfScale2.format(3.125D));
    System.out.println("dfScale2.format(3.135D)=" + dfScale2.format(3.135D));
    System.out.println("dfScale2.format(3.145D)=" + dfScale2.format(3.145D));
    System.out.println("dfScale2.format(3.225D)=" + dfScale2.format(3.225D));
    System.out.println("dfScale2.format(3.235D)=" + dfScale2.format(3.235D));
    System.out.println("dfScale2.format(3.245D)=" + dfScale2.format(3.245D));
    System.out.println();
    System.out.println("dfScale2.format(4.125D)=" + dfScale2.format(4.125D));
    System.out.println("dfScale2.format(4.135D)=" + dfScale2.format(4.135D));
    System.out.println("dfScale2.format(4.145D)=" + dfScale2.format(4.145D));
    System.out.println("dfScale2.format(4.225D)=" + dfScale2.format(4.225D));
    System.out.println("dfScale2.format(4.235D)=" + dfScale2.format(4.235D));
    System.out.println("dfScale2.format(4.245D)=" + dfScale2.format(4.245D));
  }
 }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
dfScale2.getRoundingMode()=HALF_EVEN
dfScale2.format(1.125D)=1.12
dfScale2.format(1.135D)=1.14
dfScale2.format(1.145D)=1.15
dfScale2.format(1.225D)=1.23
dfScale2.format(1.235D)=1.24
dfScale2.format(1.245D)=1.25
dfScale2.format(2.125D)=2.12
dfScale2.format(2.135D)=2.13
dfScale2.format(2.145D)=2.15
dfScale2.format(2.225D)=2.23
dfScale2.format(2.235D)=2.23
dfScale2.format(2.245D)=2.25
dfScale2.format(3.125D)=3.12
dfScale2.format(3.135D)=3.13
dfScale2.format(3.145D)=3.15
dfScale2.format(3.225D)=3.23
dfScale2.format(3.235D)=3.23
dfScale2.format(3.245D)=3.25
dfScale2.format(4.125D)=4.12
dfScale2.format(4.135D)=4.13
dfScale2.format(4.145D)=4.14
dfScale2.format(4.225D)=4.22
dfScale2.format(4.235D)=4.24
dfScale2.format(4.245D)=4.25

正確的代碼測試RoundingMode.HALF_EVEN

突然發現自己忽略了一個事情,測試的參數都是用的double類型.想起來double類型不精準.但是僥幸心理以及知識不牢靠以為 3位小數應該影響不大吧.改了下代碼,把參數改為BigDecimal類型

使用BigDecimal時,參數盡量傳入字符串,要比傳入double精準.

?
1
new BigDecimal("1.125")
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testDecimalFormat() {
  DecimalFormat dfScale2 = new DecimalFormat("###.##");
    dfScale2.setRoundingMode(RoundingMode.HALF_EVEN);
  System.out.println("dfScale2.getRoundingMode()=" + dfScale2.getRoundingMode());
      System.out.println("dfScale2.format(new BigDecimal(\"1.1251\"))=" + dfScale2.format(new BigDecimal("1.1251")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.1351\"))=" + dfScale2.format(new BigDecimal("1.1351")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.1451\"))=" + dfScale2.format(new BigDecimal("1.1451")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.2250\"))=" + dfScale2.format(new BigDecimal("1.2250")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.2350\"))=" + dfScale2.format(new BigDecimal("1.2350")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.2450\"))=" + dfScale2.format(new BigDecimal("1.2450")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.22501\"))=" + dfScale2.format(new BigDecimal("1.22501")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.23505\"))=" + dfScale2.format(new BigDecimal("1.23505")));
  System.out.println("dfScale2.format(new BigDecimal(\"1.24508\"))=" + dfScale2.format(new BigDecimal("1.24508")));
?
1
2
3
4
5
6
7
8
9
10
dfScale2.getRoundingMode()=HALF_EVEN
dfScale2.format(new BigDecimal("1.1251"))=1.13
dfScale2.format(new BigDecimal("1.1351"))=1.14
dfScale2.format(new BigDecimal("1.1451"))=1.15
dfScale2.format(new BigDecimal("1.2250"))=1.22
dfScale2.format(new BigDecimal("1.2350"))=1.24
dfScale2.format(new BigDecimal("1.2450"))=1.24
dfScale2.format(new BigDecimal("1.22501"))=1.23
dfScale2.format(new BigDecimal("1.23505"))=1.24
dfScale2.format(new BigDecimal("1.24508"))=1.25

結論

1、警覺doulbe的不精確所引起RoundingMode結果不穩定的問題,即使是四舍五入的模式,對double類型參數使用也會有不滿足預期的情況.

2、使用數字格式化時,要注意默認RoundingMode模式是否是自己需要的.如果不是記得手動設置下.

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/baixf/article/details/88792219

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产一区二区三区精品在线观看 | 亚洲一区二区观看播放 | 精品一区二区三区日本 | 欧美福利视频一区二区三区 | 国产二区三区视频 | 斗破苍穹在线观看免费完整观看 | 免费a观看| 精品一区二区三区免费毛片 | 国产在线精品一区二区三区 | 国产精品a一 | 久久综合精品视频 | 国产精品99久久久久久宅女 | 国产精品麻豆一区二区三区 | 久久嗨 | 日韩激情 | 国产va在线观看免费 | 欧美成人免费一区二区三区 | 香蕉黄色网 | 日本免费一区二区三区四区 | 伊人99在线 | 萌白酱福利视频在线网站 | 国产成人在线综合 | 久久久久久久一区二区 | 黄网站在线免费 | 色综合视频网 | 国产成人强伦免费视频网站 | 九草av| 久久精品视频黄色 | 黄色视屏免费在线观看 | 日本欧美一区二区 | 免费黄色在线观看网站 | 成人午夜久久 | 一级在线视频 | 国产精品久久久久免费视频 | 福利免费在线 | 黄色av网站免费看 | 网站激情| 国产在线精品一区二区三区 | 在线观看中文字幕av | 亚洲第一成人久久网站 | 在线观看中文字幕av |