【问题标题】:ArithmeticException divide by zero occasionallyArithmeticException 偶尔被零除
【发布时间】:2018-03-25 00:23:33
【问题描述】:

我有一个 JAVA(在 Android 上运行)方法,尽管变量 inSampleSize 在循环之前设置为 1,并且每次仅乘以 2,但由于除以零,偶尔会捕获 ArithmeticException。以下是原样的方法。知道我在这里想念什么吗?谢谢!

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    try {
        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
    } catch (ArithmeticException e) {
        LogUtil.Log("ArithmeticException=" + e.getMessage() + " inSampleSize=" + inSampleSize);
        Crashlytics.logException(e);
        inSampleSize=1;
    }
    LogUtil.Log("inSampleSize="+inSampleSize);
    return inSampleSize;
}

【问题讨论】:

  • 抛出异常时记录了什么?
  • 除以零。登录 inSampleSize 说它确实是零。看不出原因……
  • 你有没有意识到出了什么问题?我有同样的问题,很难解释

标签: java android


【解决方案1】:

乍一看,如果你将一个数字初始化为1,并且只将它乘以2,你永远不会得到0的结果。然而,在 while 循环的 32 次迭代之后,inSampleSize 的值实际上将是 0。这是因为Java忽略了int的溢出造成的。

这可以通过执行以下代码来演示:

int count = 0;
int inSampleSize = 1;
while (inSampleSize != 0) {
 count++;
 inSampleSize *= 2;
}

inSampleSize 的值为零时,此循环将终止,此时count 为32。

那么,剩下的问题是,上面的代码在什么情况下会执行while循环的32次迭代?答案是,当reqWidthreqHeight 都小于1 时。

因此,例如,如果您调用:

calculateInSampleSize(options, 0, 0);

你会看到你描述的问题。

如果reqWidthreqHeight 为零,则加载位图可能根本没有意义,因为它不可见。但是,也许您正在使用 View.getWidth()View.getHeight() 获取宽度和高度,并且在某些情况下调用太早,在视图布局之前,这些方法可能返回 0。显然,最后一点是如果不查看更多代码,猜测并且不可能知道,但我相信如果您将 reqWidthreqHeight 添加到您的日志记录中,当发生这种情况时,您会看到它们小于 1。

【讨论】:

    【解决方案2】:

    因为 height 和 halfHeight 是 int 你面临这个异常。

    final int halfHeight = height / 2;
    

    如果 height = 1 halfHeight 将在此处为 0。在你打电话的时候

    halfHeight / inSampleSize
    

    你会得到 ArithmeticException 因为 halfHeight 是 0。

    解决方案:在开始运算之前将所有度量转换为双精度或大十进制,尤其是在进行除法运算时。

    【讨论】:

      猜你喜欢
      • 2015-08-26
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多