Hi to all! I'm glab to be here and...I'm here because I need some help! ^^; Hope someone can give me an hand...


I'm trying to study java using some books for beginners...and I gest stucked in an excercise... I've this:

class LogicalOpTable {
public static void main(String args[]) {
boolean p, q;
System.out.println("P\tQ\tAND\tOR\tXOR\tNOT");

p = true; q = true;
System.out.println(p + "\t" + q + "\t" + (p&q) + "\t" + (p|q) + "\t" + (p^q) + "\t" + (!p));

p = true; q = false;
System.out.println(p + "\t" + q + "\t" + (p&q) + "\t" + (p|q) + "\t" + (p^q) + "\t" + (!p));

p = false; q = true;
System.out.println(p + "\t" + q + "\t" + (p&q) + "\t" + (p|q) + "\t" + (p^q) + "\t" + (!p));

p = false; q = false;
System.out.print(p + "\t" + q + "\t" + (p&q) + "\t");
System.out.print((p|q) + "\t" + (p^q) + "\t" + (!p));
}
}

which stamp a table of true/false combination...

Now, I've to make a table like that BUT using 1 and 0 instead of true and false...the problem is that i cannot get "!p" works with integer, it return this error:

LogicalOpTable10.java:12: operator ! cannot be applied to int
System.out.println(!p + "\t" + q + "\t" + (p&q) + "\t" + (p|q) + "\t" + (p^q) + "\t" + (!p));

I've just read this thread that was about the same problem:

http://www.daniweb.com/software-development/java/threads/82507

But they not solved that problem at all! If I try what was said there, I got the same error....

so basically is "!p" (or "intP" for the other thread) the main problem (I think...)...I can't get it to work... someone can help me to solve this ? :| in a simple way if I can ask

Many thanks and sorry for my english, I'm improving!

The '!' is called a 'Not Operator',
the not operator returns the opposite of the value.

So:

Word: 'Day', !Word: 'Night'

Or, in code speak:

p: true, !p: false

So, when you type '!p' you are asking: "What is the opposite of 1?"
Well, you and I know that is '-1'. And we would be right, except for one thing:
the not operator is a LOGIC operator. That means it only works on boolean types(true or false).

That is why it is not working. But how to fix it, I would use a third variable and
a function that checks if it is '1' or '0' and returns the other int number to the variable.

However, if you have to use that table then I don't know if you can do that.
If I come up with something else I will post it.

Hope this helps,

- WolfShield

Edited 5 Years Ago by WolfShield: n/a

Word: 'Day', !Word: 'Night'

This could be confusing, so I want to reiterate what WolfShield said: this line DOESN'T WORK THIS WAY.

The ! operator CANNOT be applied to a String, period. It is ONLY applied to a boolean, and then it negates the value given to it. That is, if the value given is true, it returns false, if false, it returns true.

You can't apply this to an int, as you've learned, or to a String, as the example quoted above would suggest.

What would be really useful for you here would be the "ternary operator". This operator takes a boolean and evaluates one of two expressions, depending on whether the boolean condition is true or false. It looks like this:

CONDITION ? TRUE_EXP : FALSE_EXP

where TRUE_EXP is the expression to evaluate if CONDITION is true, and FALSE_EXP is evaluated if it's false.

A simple case:

true ? "It's twue! It's twue!" : "You liar!"

is all one expression. Since true is always true, this will always evaluate to the first of the two strings.

To see this work, you have to put the expression into a print statement:

boolean deceit = false;

System.out.println(true ? "It's twue! It's twue!" : "You liar!");
System.out.println(deceit ? "It's twue! It's twue!" : "You liar!");
System.out.println(7%3==1 ? "It's twue! It's twue!" : "You liar!");
System.out.println(n%2==0 ? n +" is even" : (n + 1) +" is even")

There you have three examples. The first simply evaluates the boolean constant true, the second looks up a boolean variable called "deceit", which is defined to be false, and the third evaluates a boolean expression, which will return true iff the remainder of 7 divided by 3 is equal to 1. The last checks for a remainder when dividing by two and reports on whether the number is even, or its successor is. I include this so you can see that "evaluating expressions" can involve doing real work.

You can probably make some use of this to convert your truth table from the underlying boolean representation to integers.

Edited 5 Years Ago by jon.kiparsky: n/a

exactly because I can't solve this... I've added this:

int intP, intQ;

p = true; q = true;
if (p == true) intP = 1;
if (p == false) intP = 0;
if (q == true) intQ = 1;
if (q == false) intQ = 0;

but when I've to make that table, if I put intP, of course the error will still the same...I probably need some workaround to let these new variables readable like the associated booleans... ;/

@jon: probably I can, but until now the book has not yet explained these ternary operations....

It's not possible to solve this problem only with if, for and "cast" ? (I'll try understand what these ternary are, just for improve, though...)

The ?: operator is the easiest way to do it - it's generally your best bet for evaulating booleans in-line.

Your conversion is a slightly longer way to achieve the same result, and it's actually pretty close to correct. What you're doing here gives you a display value for a boolean - 1 for true, 0 for false - but you can't manipulate those display values.
One way to do it would be two write a method, call it boolToInt which would encapsulate exactly that functionality that you describe there, taking a boolean and returning the right int. Then you could print, say,

System.out.print(bootToInt(p|q) + "\t" + boolToInt(p^q) + "\t" + boolToInt(!p));

Another way to do it would be to define a variable for each place in your print string before you assemble it:

int pOrQ; 
int pXorQ;
int notP;

if (p|q) pOrQ = 1; 
else pOrQ = 0; 
if (p^q) pXorQ = 1;
else pXorQ=0;
if (!p) notP = 1;
else notP =0;
System.out.print((p|q) + "\t" + (p^q) + "\t" + (!p));

That last is probably the worst way, the only thing good about it is that it's easy for you to understand what's going on. It's very labor-intensive and very space-hungry - you have to define a variable for each place in the table, wasteful - and it is aesthetically atrocious.

I don't think you can cast a boolean to an int, and if you can someone needs to be beaten. Cast would be the wrong answer. Booleans are not equal to 1 or zero any more than bits are. Similarly, neither is equal to "Yes" or "No" or black or white or anything. Boolean variables are simply true or false, and that's the only way you should ever evaluate them. (in c, it's different, but you're not writing c).

thank u john, i'm not good enough to understand all u've said, but I've understood at least the principles ;) I'm just trying some excercise right now and I want to ask something... I've this problem:

"write a program that finds all the prime number between 1 to 100".

The solution given from the book is:

class Prime {    
  public static void main(String args[]) {    
    int i, j; 
    boolean isprime; 
 
    for(i=1; i < 100; i++) { 
      isprime = true;  
 
      // see if the number is evenly divisible 
      for(j=2; j < i/j; j++) 
        // if it is, then its not prime 
        if((i%j) == 0) isprime = false; 
 
      if(isprime) 
        System.out.println(i + " is prime."); 
    } 
  }    
}

I'm not sure but this program is wrong, right? I mean, like this it give back numbers like 9 and 25, and they are not prime cuz they are divisible for 3 or 5 respectively... I'm missing something or the books is at fault?

edit: this was a print error on the book, on their site they have wrote an errata corrige for it...using "<=" at line 10 instead of only "<". Btw, isn't a simple "j < i" enough? Why they check if it was disivible? I'm missing something? O_o

Edited 5 Years Ago by takui: n/a

Have you tried running it? I assure you, it'll work.

Step through the for loop:

for(i=1; i < 100; i++) {

for each number from 1 to 100 - this is wrong, 1 is not prime, but that's a technicality

isprime = true;

set a flag. Assume it's prime unless proved otherwise

for(j=2; j <= i/j; j++)

sub-loop: try each number greater than 1, up to i/2. Stop there because we know there's no factor of i which is greater than i/2. Quick: what is the first value for which this loop will execute?

if((i%j) == 0) isprime = false;

for each value of j, check to see whether it divides i evenly. If it does, we know that i is not prime.

if(isprime) 
        System.out.println(i + " is prime."); 
}

if we get to this statement, we've tried every integer value in the range [2..i/2], which is all of potential factors of i. If we found a factor, we set isPrime to true. So, if we didn't find a factor, there wasn't one to find, and we can say that i is prime.


Now, this works, but it's an extremely slow way to write this. It's fine for small values, but it checks a lot of values that it doesn't need to check. For example, if you know that a number is not divisible by 2, you don't need to check 4 or 8, or 236, or any other multiple of 2. So one way to fix this is to keep track of the primes and only check each potential prime against that list. This is usually called the "Sieve of Eratosthenes", after the Greek mathematician who came up with it. It's not hard to write, give it a try.

Edited 5 Years Ago by jon.kiparsky: n/a

yes john sorry, probably you catch my post when I've just corrected it! In the first time it was like i've wrote at the end on the previous on, with "<" and not "<=". In that version, it was wrong, but thank you for your big reply! I'll read it carefully now ;)

edit: a nice challenge! So i've to store in someway the prime numbers and do a check over that list? Until now I've not encountered this possibility on the book, but I'll try when I get the grasp on it for sure!

Edited 5 Years Ago by takui: n/a

This article has been dead for over six months. Start a new discussion instead.