2012-09-06 70 views
2

安全漏洞,我昨天采访了这问题就出来了:凡在这双重比较

public class Main { 

    public static void main(String[] args) { 

     // Code fragment must prints true if the double variables x and y are both 
     // strictly between 0 and 1 and false otherwise. 

     // Assuming args will be always correct (double) input, 
     // Where's the safety bug? 

     double x,y; 

     x = Double.parseDouble(args[0]); 
     y = Double.parseDouble(args[1]); 

     System.out.println((0 < x && x < 1) && (0 < y && y < 1)? true : false); 
    } 
} 

我写的有没有任何地方的错误,我的意思是,代码工作。回到家中,尝试过,确实很有效。但是,尽管我确实得到了这份工作,但这个问题是我唯一的错误,而且我无法摆脱我的头脑(这简直就是公平直截了当)。我相信我甚至不明白什么是安全错误,那么我的问题是:

什么是安全错误,这个代码的确有一个?

UPDATE:

响应后我把一些相关的资源:

Eric LippertWhy does JScript have rounding errors?

+2

既然你找到了工作,为什么你不能问问你的面试官? –

+3

问题的一部分是这个问题的含糊性。我们在谈论什么样的安全?线程安全?类型安全?安全? – Jeremy

+0

@MattBall没有说。其他候选人在下午被问到。 –

回答

3

源从评论来看:

假设ARGS将是永远正确的(双)输入,哪里是安全漏洞?

存在着上述程序将提供一个错误的输出的情况下,而且似乎是除表达式本身没有可疑的:

(0 < X & & X < 1)& & (0 <ý& &ý< 1)

铝虽然我没有测试过,但是当这个表达式遇到x或y的一个边界情况时可能有问题:NaN,+/-无穷大,甚至可能为-0.0。

此外,由于数字以double表示的有限精度(例如x = 1E-400大于0,但解析为0,所以存在可能违反用户的逻辑期望的确定有效的输入尽管用户期望真实,但表达式传递错误)。

+0

+1我用0.1 0.9999999999999999999999进行了测试,结果是错误的。很奇怪(对我来说,我显然不是专家)。我开始相信这是关于类型安全的@Jeremy建议的。问题是,如何防止精确度问题。只能通过种植或限制投入或有其他方法? –

+0

@RandolfRincón-Fadul浮点数只是数学中已知实数的近似值。人们习惯于处理数字的十进制近似值,但由于我们使用的计算机架构,fp数字使用二进制近似值,而这些近似值并不总是与小数点匹配。此外,还有精确度有限,因此0.9(20)的最接近表示值与1.0相同。将这种行为称为“安全漏洞”可能有点牵强,但实际上它可能令人困惑:n1在范围内,n2也在(对于用户而不是CPU),但是“范围内的n1和n2”都是假的 –

+0

当然,如果0.9(20)可以完全被认为是问题所指的“正确(双重)输入”,那么就存在这样的问题。但是,它会解析 - 在[Double.valueOf]的文档中看到一些有趣的讨论(http://docs.oracle.com/javase/6/docs/api/java/lang/Double.html#valueOf%28java.lang .String%29)。 –

0

我将同类型的安全性和未捕获的异常去,如果输入有点碰巧不是双。然后,代码只会引发异常。

+0

那么这很明显,但这更多的是稳定性而不是安全问题? (当然取决于实际使用)。 – Cubic

0

您可以将x设置为0,并且您可以为y输入0。但是这些值必须是之间

你最好使用strictfp。 您更好地利用0D而不是0

+0

不,我不能。如果设置为0,则它​​将变为false,这不是问题。(我比较少用也不等)。 –