简体   繁体   English

布尔测试用例在应通过时失败

[英]Boolean test case failing when it should pass

I am refreshing myself with some Java practice problems to help teach some friends of mine how to code and, embarrassingly enough, I am failing a single test case on a seemingly easy test case and can't see what I am doing wrong. 我正在刷新一些Java练习问题,以帮助教给我的一些朋友如何编码,而且令人尴尬的是,我在一个看似简单的测试用例上失败了一个测试用例,看不到我做错了什么。 The practice question is: 实践问题是:

Given 2 int values, return true if one is negative and one is positive. 给定2个int值,如果一个为负且一个为正,则返回true。 Except if the parameter negative is true, then return true only if both are negative. 除非参数negative为true,否则仅当两个参数均为负时才返回true。

My code is: 我的代码是:

public boolean posNeg(int a, int b, boolean negative) {
  if(negative == true && (a < 0 && b < 0))
    return true;
  else if(negative == false && (a < 0 && b > 0) || (a > 0 && b < 0))
    return true;

  return false;
}

And the test case is: posNeg(1, -1, true) -> false (My output is true which is incorrect.) 测试用例是: posNeg(1, -1, true) -> false(我的输出是true,这是不正确的。)

A shorter version is 较短的版本是

public boolean posNeg(int a, int b, boolean negative) {
    return (negative ? a & b : a ^ b) < 0;
}

This works because a & b is negative iff both are negative and a ^ b is negative iff one, and only one is negative. 之所以可行,是因为a & b为负(如果两者均为负),而a ^ b为负(如果仅当一个为负)。

If you used int with 0 = false and 1 = true instead of boolean as C (and byte code) does you could write 如果您使用int使用0 = false和1 = true而不是布尔值作为C(和字节码),则可以编写

public int posNeg(int a, int b, int neg) {
    return (neg * (a & b) + (1 - neg) * (a ^ b)) >>> -1;
}

One trick here is that >>> -1 gives you the top bit as 0 or 1 for both int and long . 这里的一个窍门是>>> -1intlong都给出0或1的最高位。

Your output is ok, you should change 您的输出正常,应该更改

if( negative == false && (a < 0 && b > 0) || (a > 0 && b < 0))

to

if(  !negative &&  ( (a < 0 && b > 0)  || (a > 0 && b < 0) ) ) 
                   ^                                       ^

&& works like multiplication &&就像乘法一样

If you have this 如果你有这个

negative == false && (a < 0 && b > 0) || (a > 0 && b < 0)

is like 就好像

 ( negative == false && (a < 0 && b > 0) )  || (a > 0 && b < 0)
 ^                                       ^

Try simplifying it like this. 尝试像这样简化它。

public boolean posNeg(int a, int b, boolean negative) {
  if (negative) return a < 0 && b < 0;
  else return 1L * a * b < 0L;
}

This is the culprit: 这是罪魁祸首:

else if(negative == false && (a < 0 && b > 0) || (a > 0 && b < 0))

That breaks down into: 分解为:

else if(
    negative == false && (a < 0 && b > 0)
    ||
    (a > 0 && b < 0)
)

Eg, it doesn't care about the value of negative if the condition after the || 例如,如果||之后的条件,则不在乎negative is true, it follows the path and returns true . 为true,它遵循路径并返回true

You probably want parens in there somewhere. 您可能想在那儿放一个parens。 I haven't fully worked through your logic, but possibly you meant: 我尚未完全了解您的逻辑,但可能是您的意思:

else if(
    negative == false && (
        (a < 0 && b > 0)
        ||
        (a > 0 && b < 0)
    )
)
public boolean posNeg(int a, int b, boolean negative)
{
  if(negative)
  {
      return a < 0 && b < 0;
  } else
  {
      return (long) a * b < 0;
  }
}

This is translated what you said. 这就是你所说的。 Note the smart way of checking if only one is negative: 注意检查是否只有一个为负数的聪明方法:

  • - * - = + - * - = +
  • - * + = - - * + = -
  • + * - = - + * - = -
  • + * + = + + * + = +

But as @peter.petrov pointed out: this might overflow if your integers are too big. 但正如@ peter.petrov指出的那样:如果您的整数太大,则可能会溢出。 That is why the cast to the long is required. 这就是为什么需要强制转换。 So a better nice way to check this is to do: 因此,检查此问题的更好的好方法是:

(a < 0) ^ (b < 0)

Which makes a nice one-liner, using the ternary conditional operator: 使用三元条件运算符可以很好地完成一线工作:

public static boolean posNeg(int a, int b, boolean negative)
{
    return negative ? a < 0 && b < 0 : ((a < 0) ^ (b < 0));
}

The problem seems to lie in the row: 问题似乎出在行中:

else if(negative == false && (a < 0 && b > 0) || (a > 0 && b < 0))

you're writing (false AND false OR true), so the OR case is evaluated to true, thus entering the if-statement. 您正在编写(false AND false OR true),所以OR的大小写被评估为true,从而输入了if语句。 try writing it like this instead: 尝试像这样编写它:

else if (!negative && ((a < 0 && b > 0 ) || (a > 0 && b < 0)))

that is: (false AND (false OR true)), evaluating the negative flag each time 即:(false AND(false OR true)),每次评估负标志

You can do this way too : 您也可以这样做:

public boolean posNeg(int a, int b, boolean negative) {
    int a1 = Integer.numberOfLeadingZeros(a);
    int b1 = Integer.numberOfLeadingZeros(b);
    return negative ? (a1 + b1) == 0 : ((a1 & b1) == 0 && (a1 != b1));
}

Explanation : 说明:

  • If negative is true , you want to return true if both numbers are negative so it implies that the left most bit of both number are a 1, so numberOfLeadingZeros will return 0 for both. 如果negative为true ,则如果两个数字均为负,则要返回true ,这意味着两个数字的最左位为1,因此numberOfLeadingZeros都会为两个返回0。
  • If negative is false , then if (a1 & b1 == 0) , that means that one of the numbers is negative, but it can also means that both are negative, so you have to check that a1 != b1 . 如果negative为false ,则如果(a1 & b1 == 0) ,则意味着其中一个数字为负,但也可能意味着两个数字均为负,因此必须检查a1 != b1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM