Java意外的Double / Float舍入

时间:2011-09-09 15:48:48

标签: java floating-point double rounding

任何人都可以解释以下行为吗?这个方法应该对加载的图片进行缩放,以便它可以在某些范围内尽可能大而不会过度。

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=1920idealHeight=925运行此命令,则调试变量列表会显示idealHeight = (float) 2.0。同样,我的测试图片是532x783,imgRatio = (float) 0.0。 ScaleFactor做同样的事情:532x783图像产生ScaleFactor = (double) 1.0

当我最初开始修复此问题时,我无意中将比率变量(idealRatioimgRatio)声明为int s。我看到了这一点,把它们改成了双打,并做了一个干净的构建,认为它是固定的。然后我在双打不起作用后将它们改为浮子。现在我很难过。为什么Java仍然表现得像int一样?

3 个答案:

答案 0 :(得分:5)

这是标准的Java(以及大多数静态类型语言,感谢Daniel)的行为。你在这里做的是整数除法,它总是返回一个整数(与除法运算中的值相同的类型),除非你采取措施来防止它。您可以将变量设置为浮点数/双精度数或将其转换为浮点数/双精度数,以使除法表达式返回带有标准舍入的浮点数/双精度。

答案 1 :(得分:3)

嗯,首先,5/7是一个整数表达式。

(显然,经过非常简短的审查后,其他部门也是如此。)

答案 2 :(得分:1)

仅供参考,您不能将结果分配给double并让Java执行双精度除法,您需要将每个整数项转换为双精度,如下所示:

int x=4;
int y=19;
double z = (double)x/(double)y;