Java 算术异常偶尔被零除

Java 算术异常偶尔被零除,java,android,Java,Android,我有一个JAVA(在Android上运行)方法,它偶尔会捕获由于被零除而导致的算术异常,尽管变量inSampleSize在循环之前被设置为1,并且每次只被乘以2。以下是目前的方法。你知道我在这里遗漏了什么吗?谢谢 public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of i

我有一个JAVA(在Android上运行)方法,它偶尔会捕获由于被零除而导致的算术异常,尽管变量inSampleSize在循环之前被设置为1,并且每次只被乘以2。以下是目前的方法。你知道我在这里遗漏了什么吗?谢谢

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;
}

因为“高度”和“半高”为int,所以您将面临此异常

final int halfHeight = height / 2;
如果高度=1半高,这里将为0。当你打电话的时候

halfHeight / inSampleSize
您将得到算术异常,因为半高为0


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

乍一看,如果将数字初始化为
1
,并且只将其乘以
2
,则永远不会得到
0
的结果。但是,在对
while
循环进行32次迭代后,
inSampleSize
的值实际上将是
0
。这是因为Java忽略了
int
的溢出

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

int count = 0;
int inSampleSize = 1;
while (inSampleSize != 0) {
 count++;
 inSampleSize *= 2;
}
当采样大小
inSampleSize
的值为零时,此循环将终止,此时
count
为32

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

例如,如果您打电话:

calculateInSampleSize(options, 0, 0);
你会看到你所描述的问题


如果
reqWidth
reqHeight
为零,则加载位图可能毫无意义,因为它将不可见。但是,可能您正在使用
View.getWidth()
View.getHeight()
获取宽度和高度,并且在某些情况下调用得太早,在布局视图之前,这些方法可能返回0。显然,这最后一位是一个猜测,如果看不到更多的代码,就不可能知道,但是我相信,如果您将
reqWidth
reqHeight
添加到日志中,您会发现它们小于1。

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