最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2021年10月12日 11:07:52   作者:智鼎在線IT團(tuán)隊  
這篇文章主要介紹了Java DecimalFormat 保留小數(shù)位及四舍五入的陷阱,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

需求

業(yè)務(wù)需要導(dǎo)出的Excel的數(shù)字內(nèi)容保留兩位小數(shù),并且四舍五入

代碼實現(xiàn)

百度一圈所抄襲的代碼

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

發(fā)現(xiàn)問題

導(dǎo)出數(shù)據(jù)很詭異.不是所有數(shù)據(jù)都是如所想的四舍五入.

經(jīng)過排查最終發(fā)現(xiàn)是RoundingMode的問題,應(yīng)該使用HALF_UP,

DecimalFormat 默認(rèn)使用的是HALF_EVEN

DecimalFormat dfScale2 = new DecimalFormat("###.##");
System.out.println("dfScale2.getRoundingMode()=" + dfScale2.getRoundingMode());
//輸出結(jié)果
dfScale2.getRoundingMode()=HALF_EVEN
//

RoundingMode.HALF_EVEN

想了解HALF_EVEN,去官網(wǎng)API看了下

HALF_EVEN 被舍位是5(如保留兩位小數(shù)的2.115),后面還有非0值進(jìn)1(如保留兩位小數(shù)的2.11500001 格式化為2.12),5后面沒有數(shù)字或者都是0時,前面是偶數(shù)則舍,是奇數(shù)則進(jìn)1,目標(biāo)是讓被舍前一位變?yōu)榕紨?shù).

  • 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 設(shè)置這個模式,對于精確值格式化會拋出異常
  • Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.
  • UP 向遠(yuǎn)離數(shù)字0進(jìn)行進(jìn)位.
  • Rounding mode to round away from zero.

錯誤的代碼測試RoundingMode.HALF_EVEN

為了更好的理解HALF_EVEN,寫了些測試代碼但是發(fā)現(xiàn)自己更迷惘了…搞不清楚到底HALF_EVEN是什么機(jī)制進(jìn)舍…輸出結(jié)果的尾數(shù)很不規(guī)律.

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
public class LocalTest {
//定義一個保留兩位小數(shù)格式的 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));
  }
 }
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

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

使用BigDecimal時,參數(shù)盡量傳入字符串,要比傳入double精準(zhǔn).

new BigDecimal("1.125")
  @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")));
   
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

結(jié)論

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

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

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

大理市| 陆河县| 泸水县| 如皋市| 岳阳市| 垫江县| 峡江县| 马鞍山市| 东乡县| 慈溪市| 高雄市| 曲阜市| 广东省| 锡林浩特市| 宿松县| 和硕县| 宜兰县| 华亭县| 涿州市| 邓州市| 璧山县| 习水县| 禄丰县| 栾川县| 龙胜| 海淀区| 广西| 贺兰县| 小金县| 罗平县| 合江县| 南昌市| 稷山县| 白水县| 石首市| 沙湾县| 滦平县| 昭觉县| 沭阳县| 和田县| 静安区|