簡體   English   中英

distanceTo() integer 溢出?

[英]distanceTo() integer overflow?

這是我確定兩點之間距離的方法:


    // Euclidean distance between this point and that point
    public int distanceTo(Point that) {
        int distanceX = this.x - that.x;
        int distanceY = this.y - that.y;
        return (int) Math.sqrt(distanceX * distanceX + distanceY * distanceY);
    }

是否可能發生 integer 溢出,如果是,我該如何防止?

編輯:

在此處輸入圖像描述

為防止溢出導致不正確的結果,請使用Math “精確”方法:

1)或long變體。

如果發生溢出,這些方法將拋出ArithmeticException

public int distanceTo(Point that) throws ArithmeticException {
    int distanceX = Math.subtractExact(this.x, that.x);
    int distanceY = Math.subtractExact(this.y, that.y);
    return (int) Math.sqrt(Math.addExact(Math.multiplyExact(distanceX, distanceX),
                                         Math.multiplyExact(distanceY, distanceY)));
}

當然,謹慎的做法是使用long數學來最小化溢出的可能性。

public int distanceTo(Point that) {
    long distanceX = Math.subtractExact((long) this.x, (long) that.x);
    long distanceY = Math.subtractExact((long) this.y, (long) that.y);
    long sumOfSquares = Math.addExact(Math.multiplyExact(distanceX, distanceX),
                                      Math.multiplyExact(distanceY, distanceY));
    return Math.toIntExact((long) Math.sqrt(sumOfSquares));
}

sumOfSquares擴展為double時,精度可能會略有下降,但在轉換為long期間丟棄小數點時,精度可能會丟失。

首先你可以使用斜邊function。

然后 integer 溢出可能發生在遠處( - )。

解決方案是使用double,因為最終結果是使用浮點數function計算的。

結果可能與sqrt(2)*2*Integer.MAX_VALUE一樣大,也會溢出。

所以:

public int distanceTo(Point that) {
    double distanceX = ((double)this.x) - that.x;
    double distanceY = ((double)this.y) - that.y;
    double distance = Math.hypot(distanceX, distanceY);
    if (distance + 1 >= Integer.MAX_VALUE) {
        throw new ArithmeticException("Integer overflow");
    }
    return (int) distance; // (int) Math.round?
}

或者更整潔(就像 Andreas 一樣):

public int distanceTo(Point that) {
    double distanceX = ((double)this.x) - that.x;
    double distanceY = ((double)this.y) - that.y;
    double distance = Math.hypot(distanceX, distanceY);
    return Math.toIntExact((long)distance); // (int) Math.round?
}

這是我確定兩點之間距離的方法:


    // Euclidean distance between this point and that point
    public int distanceTo(Point that) {
        int distanceX = this.x - that.x;
        int distanceY = this.y - that.y;
        return (int) Math.sqrt(distanceX * distanceX + distanceY * distanceY);
    }

是否可能發生整數溢出,如果是,我該如何防止?

編輯:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM