日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BigDecimal丢失精度的坑

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BigDecimal丢失精度的坑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題:new BigDecimal(double d)的數值居然還是不精確的

double d = 0.09; BigDecimal bigDecimal=new BigDecimal(d); System.out.println(bigDecimal); System.out.println(d);

輸出結果:

0.0899999999999999966693309261245303787291049957275390625

0.09

?

原因:BigDecimal將double數據轉換成為long bits,進行移位計算數值,而double的long bits移位計算是無法得到0.09的精確數值,所有造成數據精度丟失。

為了避免丟失double的數據精度,將double數據轉成String,使用BigDecimal(String s)構造方法。

public class BigDecimal extends Number implements Comparable<BigDecimal>{public BigDecimal(double val) {this(val,MathContext.UNLIMITED);}public BigDecimal(double val, MathContext mc) {if (Double.isInfinite(val) || Double.isNaN(val))throw new NumberFormatException("Infinite or NaN");// Translate the double into sign, exponent and significand, according// to the formulae in JLS, Section 20.10.22.long valBits = Double.doubleToLongBits(val);int sign = ((valBits >> 63) == 0 ? 1 : -1);int exponent = (int) ((valBits >> 52) & 0x7ffL);long significand = (exponent == 0? (valBits & ((1L << 52) - 1)) << 1: (valBits & ((1L << 52) - 1)) | (1L << 52));exponent -= 1075;// At this point, val == sign * significand * 2**exponent./** Special case zero to supress nonterminating normalization and bogus* scale calculation.*/if (significand == 0) {this.intVal = BigInteger.ZERO;this.scale = 0;this.intCompact = 0;this.precision = 1;return;}// Normalizewhile ((significand & 1) == 0) { // i.e., significand is evensignificand >>= 1;exponent++;}int scale = 0;// Calculate intVal and scaleBigInteger intVal;long compactVal = sign * significand;if (exponent == 0) {intVal = (compactVal == INFLATED) ? INFLATED_BIGINT : null;} else {if (exponent < 0) {intVal = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal);scale = -exponent;} else { // (exponent > 0)intVal = BigInteger.valueOf(2).pow(exponent).multiply(compactVal);}compactVal = compactValFor(intVal);}int prec = 0;int mcp = mc.precision;if (mcp > 0) { // do roundingint mode = mc.roundingMode.oldMode;int drop;if (compactVal == INFLATED) {prec = bigDigitLength(intVal);drop = prec - mcp;while (drop > 0) {scale = checkScaleNonZero((long) scale - drop);intVal = divideAndRoundByTenPow(intVal, drop, mode);compactVal = compactValFor(intVal);if (compactVal != INFLATED) {break;}prec = bigDigitLength(intVal);drop = prec - mcp;}}if (compactVal != INFLATED) {prec = longDigitLength(compactVal);drop = prec - mcp;while (drop > 0) {scale = checkScaleNonZero((long) scale - drop);compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);prec = longDigitLength(compactVal);drop = prec - mcp;}intVal = null;}}this.intVal = intVal;this.intCompact = compactVal;this.scale = scale;this.precision = prec;} }

?

總結

以上是生活随笔為你收集整理的BigDecimal丢失精度的坑的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。