亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 equals() 方法中比較雙精度的正確方法

在 equals() 方法中比較雙精度的正確方法

慕容3067478 2023-09-13 10:51:23
我的類中有雙精度類型,并且必須重寫 equals()/hashCode()。所以我需要比較雙精度值。哪個是正確的方法?版本1:boolean isEqual(double a, double b){    return Double.doubleToLongBits(a) == Double.doubleToLongBits(b);}版本2:boolean isEqual(double a, double b){    final double THRESHOLD = .0001;    return Math.abs(a - b) < THRESHOLD;}double或者我應該完全避免原始并使用它的包裝類型Double?這樣我就可以使用Objects.equals(a,b), ifa和bare Double 。
查看完整描述

2 回答

?
三國紛爭

TA貢獻1804條經驗 獲得超7個贊

在 equals/hashcode 方法中推薦使用的方法[需要引用]是分別使用Double.doubleToLongBits()Double.hashcode()。

這是因為如果哈希碼不同,則 equals 合約要求兩個輸入的計算結果為“不同”。反之則沒有限制。

(注意:事實證明Double.compare()內部使用,doubleToLongBits()但 API 沒有指定。因此我不會推薦它。另一方面,hashCode() 確實指定它使用doubleToLongBits()。)

實際例子:

@Override

public boolean equals(Object obj) {

    if (obj == null || getClass() != obj.getClass())

        return false;


    Vector2d other = (Vector2d)obj;

    return Double.doubleToLongBits(x) == Double.doubleToLongBits(other.x) &&

           Double.doubleToLongBits(y) == Double.doubleToLongBits(other.y);

}


@Override

public int hashCode() {

    int hash = 0x811C9DC5;

    hash ^= Double.hashCode(x);

    hash *= 0x01000193;

    hash ^= Double.hashCode(y);

    hash *= 0x01000193;

    return hash;

}


查看完整回答
反對 回復 2023-09-13
?
DIEA

TA貢獻1820條經驗 獲得超2個贊

double不應該用作建立對象相等性及其hashcode的組件。

這是因為浮點數存在固有的不精確性,并且人為地雙飽和+/-Infinity

為了說明這個問題:

System.out.println(Double.compare(0.1d + 0.2d, 0.3d));
System.out.println(Double.compare(Math.pow(3e27d, 127d), 17e256d / 7e-128d));

印刷:

1
0

...這轉化為以下兩個錯誤陳述

0.1+0.2>0.3

(3 * 1027)127 == 17 * 10256 / (7 * 10-128)

因此,你的軟件會讓你對兩個不相等的相等數字或兩個非常大或非常小的不相等數字相等采取行動。


查看完整回答
反對 回復 2023-09-13
  • 2 回答
  • 0 關注
  • 126 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號