亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

Java正確比較浮點(diǎn)數(shù)的方法

瀏覽:99日期:2022-08-21 13:40:32

看下面這段代碼,將 d1 和 d2 兩個(gè)浮點(diǎn)數(shù)進(jìn)行比較,輸出的結(jié)果會(huì)是什么?

double d1 = .1 * 3;double d2 = .3;System.out.println(d1 == d2);

按照正常邏輯來看,d1經(jīng)過計(jì)算之后的結(jié)果應(yīng)該是0.3,最后打印的結(jié)果應(yīng)該是 true,對吧?但是運(yùn)行一下就會(huì)發(fā)現(xiàn)結(jié)果并不是 true 而是 false 。

輸出一下 d1,發(fā)現(xiàn)得到的答案不是想象中的 0.3 而是 0.30000000000000004,所以和 d2 進(jìn)行比較結(jié)果自然是 false

如何正確地比較浮點(diǎn)數(shù)(單精度的 float 和雙精度的 double),不單單是 Java 特定的問題,在計(jì)算機(jī)的內(nèi)存中,存儲(chǔ)浮點(diǎn)數(shù)時(shí)使用的是 IEEE 754 標(biāo)準(zhǔn),就會(huì)有精度的問題。

存儲(chǔ)和轉(zhuǎn)換的過程中浮點(diǎn)數(shù)容易引起一些較小的舍入誤差,正是這個(gè)原因,導(dǎo)致在比較浮點(diǎn)數(shù)的時(shí)候,不能使用“==”操作符——要求嚴(yán)格意義上的完全相等。

那么如何正確的比較浮點(diǎn)數(shù)呢?這里有兩種方案。

第一種方案是允許兩個(gè)值之間存在一點(diǎn)誤差(指定一個(gè)閾值),使用 Math.abs() 方法來計(jì)算兩個(gè)浮點(diǎn)數(shù)之間差異的絕對值,如果這個(gè)差異在閾值范圍之內(nèi),我們就認(rèn)為兩個(gè)浮點(diǎn)數(shù)是相等的。

final double THRESHOLD = .0001;double d1 = .1 * 3;double d2 = .3;if(Math.abs(d1-d2) < THRESHOLD) {System.out.println('d1 和 d2 相等');} else {System.out.println('d1 和 d2 不相等');}

Math.abs() 方法用來返回 double 的絕對值,如果 double 小于 0,則返回 double 的正值,否則返回 double。也就是說,abs() 后的結(jié)果絕對大于 0,如果結(jié)果小于閾值(THRESHOLD),我們就認(rèn)為 d1 和 d2 相等。

第二種方案是使用 BigDecimal 類,可以指定要舍入的模式和精度,這樣就可以解決舍入的誤差。

以使用 BigDecimal 類的 compareTo() 方法對兩個(gè)數(shù)進(jìn)行比較,該方法將會(huì)忽略小數(shù)點(diǎn)后的位數(shù),怎么理解這句話呢?比如說 2.0 和 2.00 的位數(shù)不同,但它倆的值是相等的。

a.compareTo(b) 如果 a 和 b 相等,則返回 0,否則返回 -1。

tips: 不要使用 equals() 方法對兩個(gè) BigDecimal 對象進(jìn)行比較,這是因?yàn)?equals() 方法會(huì)考慮位數(shù),如果位數(shù)不同,則會(huì)返回 false,盡管數(shù)學(xué)值是相等的。

BigDecimal a = new BigDecimal('2.00');BigDecimal b = new BigDecimal('2.0');System.out.println(a.equals(b));System.out.println(a.compareTo(b) == 0);

上面的代碼中 a.equals(b) 的結(jié)果就為 false,因?yàn)?2.00 和 2.0 小數(shù)點(diǎn)后的位數(shù)不同,但 a.compareTo(b) == 0 的結(jié)果就為 true,因?yàn)?2.00 和 2.0 在數(shù)學(xué)層面的值的確是相等的。

compareTo() 方法比較的過程非常嚴(yán)謹(jǐn),源碼如下:

private int compareMagnitude(BigDecimal val) { // Match scales, avoid unnecessary inflation long ys = val.intCompact; long xs = this.intCompact; if (xs == 0) return (ys == 0) ? 0 : -1; if (ys == 0) return 1; long sdiff = (long)this.scale - val.scale; if (sdiff != 0) { // Avoid matching scales if the (adjusted) exponents differ long xae = (long)this.precision() - this.scale; // [-1] long yae = (long)val.precision() - val.scale; // [-1] if (xae < yae) return -1; if (xae > yae) return 1; if (sdiff < 0) { // The cases sdiff <= Integer.MIN_VALUE intentionally fall through. if ( sdiff > Integer.MIN_VALUE && (xs == INFLATED || (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) && ys == INFLATED) {BigInteger rb = bigMultiplyPowerTen((int)-sdiff);return rb.compareMagnitude(val.intVal); } } else { // sdiff > 0 // The cases sdiff > Integer.MAX_VALUE intentionally fall through. if ( sdiff <= Integer.MAX_VALUE && (ys == INFLATED || (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) && xs == INFLATED) {BigInteger rb = val.bigMultiplyPowerTen((int)sdiff);return this.intVal.compareMagnitude(rb); } } } if (xs != INFLATED) return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1; else if (ys != INFLATED) return 1; else return this.intVal.compareMagnitude(val.intVal);}

接下來,用 BigDecimal 來解決開頭的問題。

BigDecimal d1 = new BigDecimal('0.1');BigDecimal three = new BigDecimal('3');BigDecimal d2 = new BigDecimal('0.3');d1 = d1.multiply(three);System.out.println('d1 = ' + d1);System.out.println('d2 = ' + d2);System.out.println(d1.compareTo(d2));

程序輸出的結(jié)果如下:

d1 = 0.3d2 = 0.30

d1 和 d2 都為 0.3,所以 compareTo() 的結(jié)果就為 0,表示兩個(gè)值是相等的。

總結(jié)一下,在遇到浮點(diǎn)數(shù)的時(shí)候,千萬不要使用 == 操作符來進(jìn)行比較,因?yàn)橛芯葐栴}。要么使用閾值來忽略舍入的問題,要么使用 BigDecimal 來替代 double 或者 float。

以上就是Java正確比較浮點(diǎn)數(shù)的方法的詳細(xì)內(nèi)容,更多關(guān)于Java 正確比較浮點(diǎn)數(shù)的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 免费高清成人啪啪网站 | 日本精品一区二区三区在线 | 久久久全国免费视频 | 尤物精品在线 | a级粗大硬长爽猛视频免费 a级精品国产片在线观看 | 日韩欧美亚州 | 爱呦视频在线播放网址 | 国产成人经典三级在线观看 | 爱爱欧美视频 | 污91视频 | 成人高清视频在线观看大全 | 九九热精品视频在线 | 九色在线免费观看 | 国产精品美女一区二区三区 | 国产三级一区二区三区 | a级毛片免费高清毛片视频 a级毛片免费播放 | 伊人网国产| 丁香六月婷婷精品免费观看 | 一级毛片免费视频网站 | 国产男女交性视频播放 | 亚洲国产精品成人久久 | 国产免费小视频在线观看 | 日韩一线| 色佬在线| 国产三级精品三级国产 | 欧洲美女a视频一级毛片 | 国产人妖在线观看一区二区 | 亚洲一区二区成人 | 男女激情网 | 成人欧美一区二区三区视频不卡 | 国产xxxx色视频在线观看14 | 色一情一乱一伦一区二区三区 | 亚洲网视频 | 国产日产精品久久久久快鸭 | 99玖玖| 97视频在线观看免费 | 欧美三级在线观看黄 | 一级特级毛片 | 亚洲精品国产不卡在线观看 | 成人午夜大片免费看爽爽爽 | 亚洲人和日本人hd |