簡體   English   中英

在 Java 中如何從 double 轉換為 int?

[英]How does conversion from double to int work in Java?

對於以下代碼(Java):

double d = (double) m / n; //m and n are integers, n>0
int i = (int) (d * n);

i == m

最后一個表達式總是正確的嗎? 如果不是,這總是正確的嗎?:

i = (int) Math.round(d * n);

i == m

int i = (int) (d * n); i == m;

對於 m=1,n=49,這是錯誤的。

i = (int) Math.round(d * n); i == m;

我的直覺告訴我這應該是真的,但可能很難嚴格證明。

您提出的第二個問題涉及 Java 中的ulp有多大。

如果 ulp 超過1/(n) ,則乘法四舍五入將不會恢復原始除法整數。 通常,較大的 ulp 與較大的雙精度值相關聯。 與雙精度相關的 ulp 在 9E15 左右開始超過 1; 如果您恢復的雙打就在那里,那么您可能會發現 round() 沒有得到預期答案的問題。 但是,當您使用 int 值時,除法分子的最大值將是Integer.MAX_VALUE

以下程序測試n的所有正 integer 值,以查看在嘗試恢復已划分的 int 時哪一個導致舍入誤差的最大可能性:

  public static void main(String[] args)
  {
    // start with large number
    int m = Integer.MAX_VALUE;
    double d = 0;

    double largestError = 0;
    int bigErrorCause = -1;
    for (int n = 1; n < Integer.MAX_VALUE; n++)
    {
      d = (double) m / n;
      double possibleError = Math.ulp(d) * n;
      if (possibleError > largestError)
      {
        largestError = possibleError;
        bigErrorCause = n;
      }
    }
    System.out.println("int " + bigErrorCause + " causes at most "
        + largestError + " error");
  }

output 是:

int 1073741823 最多導致 4.768371577590358E-7 錯誤

使用 Math.round 進行舍入,然后轉換為 int 應該恢復原始 int。

從數學上講,它應該是正確的。 但是,您可能會遇到浮點舍入錯誤,從而使其錯誤。 您幾乎不應該使用==比較浮點精度數。

你最好使用這樣的閾值來比較它們:

Math.abs( d*n - m ) < 0.000001;

注意這兩個語句應該是等價的

i = (int) (d * n);
i = (int) Math.round(d * n);

但是,例如,如果d=3/2n=2 ,浮點錯誤可能會導致i=2.999999999999在截斷/舍入后為 2。

第一個絕對不總是正確的。 第二個我會說是的,這是真的,但只是因為我想不出一個反例。

如果 n 非常大,它可能是錯誤的,我不確定。 我知道這至少在 99% 的情況下都是正確的。

暫無
暫無

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

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