Java的Double/Float意外舍入 [英] Java Unexpected Rounding of Double/Float

查看:47
本文介绍了Java的Double/Float意外舍入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以解释以下行为吗?该方法应该缩放加载的图片,以使其在不超出范围的前提下尽可能大.

Can anyone explain the following behavior? This method is supposed to scale the loaded picture so that it is as large as it can be within certain bounds without going over.

private final File imageFile;
private final ImageLoaderListener listener;
private final int idealWidth;
private final int idealHeight;
private final float idealRatio;

@Override
protected BufferedImage doInBackground() throws Exception {
    BufferedImage origImage;
    BufferedImage scaledImage;
    int origHeight;
    int origWidth;
    float imgRatio;

    // Load the image.
    try {
        origImage = ImageIO.read( imageFile );
        origHeight = origImage.getHeight();
        origWidth = origImage.getWidth();
        imgRatio = origWidth / origHeight;
        //imgRatio = 5/7;
    } catch (Exception e){
        JOptionPane.showMessageDialog( AppFrame.getAppFrame(),
                "Could not load the image.", "Error Loading Image",
                JOptionPane.ERROR_MESSAGE );
        return null;
    }

    // Scale the image
    double scaleFactor = (imgRatio >= idealRatio) ? idealWidth/origWidth
                                                  : idealHeight/origHeight;
    int scaledWidth = (int) Math.floor( scaleFactor * origWidth );
    int scaledHeight = (int) Math.floor( scaleFactor * origHeight );

    scaledImage = new BufferedImage( scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB );
    AffineTransform at = new AffineTransform();
    at.scale(scaleFactor, scaleFactor);
    AffineTransformOp scaleOp = new AffineTransformOp( 
            at, AffineTransformOp.TYPE_BICUBIC );
    scaledImage = scaleOp.filter(origImage, scaledImage);

    return scaledImage;
}

这是出乎意料的结果:所有除法运算都在不通知我的情况下取整.因此,如果我使用 idealWidth = 1920 idealHeight = 925 运行此程序,则调试变量列表将显示 idealHeight =(float)2.0 .同样,我的测试图片为532x783,并且 imgRatio =(float)0.0 .ScaleFactor在做同样的事情:532x783图像导致 ScaleFactor =(double)1.0

This is the unexpected result: All of the division is rounding without my telling it to. So if I run this with idealWidth=1920 and idealHeight=925, the debug variable list shows idealHeight = (float) 2.0. Likewise, my test picture is 532x783, and imgRatio = (float) 0.0. ScaleFactor is doing the same thing: the 532x783 image results in ScaleFactor = (double) 1.0

当我最初开始对此进行错误修正时,我无意中将比率变量( idealRatio imgRatio )声明为 int s.我看到了,将它们更改为两倍,并进行了干净的构建,以为已修复.然后在双打不起作用后,我将它们更改为浮点数.现在我很困惑.到底为什么Java仍然会像 int s一样起作用?

When I originally started to bugfix this, I had inadvertently declared the ratio variables (idealRatio and imgRatio) as ints. I saw this, changed them to doubles, and did a clean build, thinking it was fixed. Then I changed them to floats after doubles didn't work. Now I'm stumped. Why on earth would Java still be acting as if they were ints?

推荐答案

这是标准Java(感谢Daniel,也是大多数静态类型的语言)的行为.您在此处执行的操作是整数除法,除非您采取措施防止它返回,否则它将始终返回整数(与除法运算中的值相同的类型).您可以将变量设置为float/double,也可以将其强制转换为float/double,以使除法表达式返回带有标准舍入的float/double.

This is standard Java (and most statically typed languages, thanks Daniel) behavior. What you are doing here is integer division which will always return an integer (same type as values in division operation) unless you take measures to prevent it. You could either make the variables into floats/doubles or cast one to a float/double to have the division expression return a float/double with standard rounding.

这篇关于Java的Double/Float意外舍入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆