logical OR and modulus operator behaving oddly in Java - java

I'm trying to build an array of prime numbers in Java.
if(c % 2 != 0 || c % 3 != 0 || c % 5 != 0) {
n.add(c);
}
But my program seems to ignore the condition and just adds every number to my list.
But if I just use one condition for example,
if(c % 2 != 0)
The code works perfectly in ignoring any number which is a multiple of 2. What am I missing here?

You need to use logical and (&&) instead of or(||), as you want all conditions to be true before adding.
With logical or, each condition is evaluated from left to right, until finding one that matches.

Your condition right now evaluates to true if the number is not divisible by any of (2,3,5). This holds for all numbers except multiples of (all of) 2, 3, and 5. Try logical and (&&) instead of logical or (||).

Related

Using a for loop and charAt(); to print letters of a string in alternating cases

import java.util.*;
public class BugFixes
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
altCaps("Computer Science");
}
static void altCaps(String hi)
{
String hi2 = hi;
int locate = 0;
for(int i = 0; i < hi2.length();i++)
{
if((Character.isLetter(hi2.charAt(locate))))
{
if(hi2.charAt(locate) % 2 == 0)
{
System.out.print(hi2.toLowerCase().charAt(locate));
locate++;
}
else if(hi2.charAt(locate) % 2 == 1)
{
System.out.print(hi2.toUpperCase().charAt(locate));
locate++;
}
}
else if(hi2.charAt(locate) == ' ')
{
System.out.print(" ");
locate++;
}
}
}
}
This is one of the problems that I have on my current lab. I was able to fix a few other mistakes but I can't seem to find this one.
My question is why it is outputting "COMpUtER SCIEnCE"? I don't understand what is happening here and I've been looking through it for an hour now. My goal is to output "CoMpUtEr ScIeNcE"
I thought the (hi2.charAt(locate) % 2 == 0) and vice versa would alternate between the even and odd locations in the string, but I believe I have made a mistake somewhere. I just can't find it.
Using BlueJ V3.1.7
1 year high school Computer Science Experience and currently enrolled in AP Computer Science
Any Tips?
not really. So hi2.charAt(locate) % 2 == 0 is actually checking if the integer value of the character is odd or even, but you want to actually check if the index is odd or even if I get you right. In other words:
hi2.charAt(2) % 2 == 0
Is check if m is odd or even. However, I think you want to check if 2 (the index) is odd or even. I guess from here it's easy to assume that you need to change:
if(hi2.charAt(locate) % 2 == 0)
//...
else if(hi2.charAt(locate) % 2 == 1)
//...
to
if(locate % 2 == 0)
//...
else if(locate % 2 == 1)
//...
This won't give you exactly the output you want, but it's just a matter of inverting the if conditions or the body as you wish. Also, there's no other cases for the operation % 2, meaning you'd only get either an odd or even index, so you could simplify the code by just doing:
if(locate % 2 == 0)
//...
else
//...
Which reads better. Hope this helps!
I would strongly advise refactoring your code to reduce repetative calls, and make inspection of values possible (rather than comparison of function evaluation).
For example:
char currentCharacter = hi2.charAt(locate);
would replace four instances of the function call, and allow you to inspect what the actual value is (rather than what you expect the value to be). This would likely make your error more evident.
Assuming the following values:
hi2 = "Computer Science";
locate = 0;
then it may be worth stepping through the evaluation.
0. hi2.charAt(locate) % 2 == 0
1. "Computer Science".charAt(0) % 2 == 0
2. 'C' % 2 == 0
3. 67 % 2 == 0
4. 1 == 0
5. false
The fundamental problem is that by never assigning your value to a variable, you never take the time to understand what is in it. By assigning it to the variable, you are able to inspect the value using a debugger.
By inspecting the values, we can see that you probably want the mod of 0, not 'C', therefore you probably wanted
0. locate % 2 == 0
1. 0 % 2 == 0
2. 0 == 0
3. true
Bonus
Refactoring your code to reduce repetition, would also highlight other errors. For example, try the following:
assert "CoMpUtEr sCiEnCe".equals(BugFixes.altcaps("Computer Science"));
assert "CoMpUtEr-sCiEnCe 201".equals(BugFixes.altcaps("Computer-Science 201"));
KISS: removal of needless logic would reduce the chance of things going wrong.
For starters, you don't need to reassign the string, or the locate variable, or check if a character is already a character. Just use the iteration integer, if you need it, and the parameter.
Secondly, you're modding the character, not the position.
Anyways, a simple boolean toggle would be easier to understand than modding.
void altCaps(String hi) {
boolean caps = true;
for (char ch : hi.toCharArray()) {
if (ch == ' ') {
System.out.print(ch);
}
else if (Character.isLetter(ch)) {
if (caps) System.out.print(Character.toUpperCase(ch));
else System.out.print(Character.toLowerCase(ch));
caps = !caps; // switch between upper and lower every character
}

Java confused by this syntax

boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
boolean is a true or false.
! = not
|| = or
&& = and
but I still dont understand this syntax... can someone explain me what this syntax excactly does?
Just dissect it:
There are some comparisons such as
5 > 2 ... true
3 < 5 ... true
Those two are pulled together using &&; so true && true --> true
1 < 8 ... true
That one is or'ed to the rest; so we get true or true --> true
Finally, not (true) --> false
Long story short: if you don't understand the whole picture, break it down into the parts you understand; and then pull those together again.
Edit: and of course, the order I am using in my explanation isn't what happens in reality. There, 1 < 8 is evaluated first; and as that is true; and "true or X" is always true, the other comparisons are not even computed.
The not ! operator negates what it is in front of. In this case !() it will produce the opposite of the what is inside of the parenthesis.
the || or operator checks to see if one condition or the other is true. At least one must be true for the condition to return true.
Finally the && checks both sides of the conditional statement to see if they are both true, and both of them must be true to proceed.
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
Let's parse it the way Java does :
boolean : Here comes a boolean, i.e. true or false.
riddle : The variable riddle is declared to be a boolean.
= : The boolean variable riddle is initialized with the expression on the right.
!(...) : It returns a boolean, the negation (=opposite) of the boolean inside of the parentheses.
Inside the parentheses is a bool1 || bool2 expression, where || is a "lazy OR" operator. If bool1 is true, there's no need to evaluate bool2.
bool1 is 1 < 8, which is true.
bool2 isn't evaluated
bool1 ||bool2 is true
!(...) is false
riddle is initialized with false
At no point in time are 5 > 2 or 3 < 5 evaluated. Eclipse warns that those 2 expressions are "dead code" and could be removed.
The whole expression could be :
boolean riddle = !( 1 < 8 || (5 > 2 && doSomethingVeryDangerous()));
the result would be the same and no method call would happen at all.
The problem that you have is that you initialize at the same time as you are checking if it's true or false. You cannot compare boolean with integer. If you want to do it then you need to solve it in another way by converting from one datatype to another, or involve another variable in your solution. The way you need to solve your syntax problem is by dividing it like this:
How you did it...
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
How to potentially solve it...
boolean riddle;
"...some code to decide if riddle will be true or
false and assign it to the variable riddle..."
if (riddle == true){
"...do some code here...";
}
if (riddle == false){
"...do some code here...";
}
Or you can solve the problem by not using boolean as datatype and instead only use integers like this...
int riddle;
"...some code to decide what value riddle will
have and assign it to the variable riddle..."
if ( riddle < 8 && riddle > 1){
"...do some code here...";
}

checking for unwanted input (Error Handling)

I want to check if the input my code needs is correct so I put a lot of if statements checking for the requirements and I can't figure out why it's not working. It is supposed to check if n is less or equal to 91 and / or it is a decimal (I don't want my input to be either). This is so that the user doesn't break the program by typing a decimal or a number higher than 91.
while (Error == 1) {
n = user_input.nextDouble();
if ((n - Math.round(n) <= 0.9) && (n - Math.round(n) >= 0.1)) {
System.out.println("Error: No Decimal points please, try again");
continue;
}
if ((n - Math.round(n) <= 0.9) && (n - Math.round(n) >= 0.1) && (n > 91)) {
System.out.println("Error: No Decimal points please, try again");
System.out.println("Error: Number too high, try again");
continue;
}
if (n > 91) {
System.out.println("Error: Number too high, try again");
continue;
}
if (n == Math.round(n)) {
Error = 0;
}
if (n == 0) {
break;
}
}
For some reason when I type 9.1 or 9.9 it doesn't do anything at all. It's blank...
I did >= which is supposed to check if it is bigger or equal to and <= which is supposed to check if it is less or equal to. Is that wrong?
Well, first of all, you seem to want only inputs that are integers less than or equal to 91.
It seems strange that you would say this, but then explicitly grab doubles with the nextDouble() method of Scanner.
There are better ways of checking for integers... see this question What's the best way to check to see if a String represents an integer in Java?
Either way, I'll assume you intend on sticking with your innovative methodology:
You are correct, that in regular math, 9.1 rounds to 9 and the difference between the two is less than or equal to 0.1. Your cases should work.
But welcome to the world of Java floating point algebra! Doubles don't compare well here.
What do I meant that they don't compare well? Well, the difference between your '9.1' and '9' is actually 0.09999999999999964, not 1.
Java doesn't compensate for this when you use basic comparators, so your comparison fails.
Hope is not lost! There is a better way of comparing doubles than using the regular comparison operators.
Introducing.... Double.compare()!! You can read the javadocs on that method, or you can go here for information on what that method does: some reliable tutorial site
However, what if they input 9.0001? Your test fails, even if the comparison works as you'd expect. You really should rethink your math here. As in, try this instead:
Double.compare((n - Math.round(n)),0.0) != 0)
In case of 9.1 and 9.9, none of the conditions are satisfied. That's why nothing is done. Loop is iterated and wait for next double input.
Here, the main culprit is n - Math.round(n). The calculations are not being accurate. For example, in case of 9.1:
n - Math.round(n) value is equal to 0.09999999999999964. So, the condition n - Math.round(n) >= 0.1 is never satisfied and no if block is reached.

While less than or not equal to won't terminate

I am programming a Pit scoring system and I have a piece of code that looks like this:
while(highestConverted<scoreConverted||highestConverted!=scoreConverted)
It will always return true and repeat the code within it regardless of the value of scoreConverted or highestConverted. I don't think it really matters but both values or ints which are converted from scanner variables using Integer.parseInt . I don't have that much experience with Java but I do know some of the basics.
Consider your code:
while(highestConverted<scoreConverted||highestConverted!=scoreConverted)
Let's suppose highestConverted = 5 and scoreConverted = 2.
highestConverted < 2 = 5 < 2 -> false
highestConverted != 2 -> 5 != 2 -> true
false || true = true.
So the while loop will always repeat.
It should be
while(highestConverted<scoreConverted && highestConverted!=scoreConverted)
Or, better
while(highestConverted<scoreConverted)
highestConverted<scoreConverted implicitly includes highestConverted!=scoreConverted as it will stop at scoreConverted - 1.

Is following true in java?

Is following true in java:
In java if you use || then after getting first true condition it neglects the rest conditions. That is If you write if(a || b || c) in java and java finds a is true then it will not check for b and c, just go into the if case.
Yes this is called short circuiting, if you put less expensive checks to the left you might avoid the expensive ones to follow.
This works for || and &&
one of the best uses is checking a value from an object that might be null:
if(myList != null && myList.size() > 6)
the previous line is null safe, reversing the condition will cause a null pointer exception in case myList is null
This is correct. || is called short-circuit OR evaluation, or an OR-ELSE operator.
This is important in situations when evaluating the right-hand side may cause an undesirable consequence:
if (myString == null || myString.indexOf("hello") != -1)
...
would crash if it were not for short-circuiting.
Yes, This way the compiler avoids unnecessary checking and calculation overhead.
That's correct, and that's not just laziness on part of the language implementation, but rather it is a crucial feature - short-circuiting allows you to write something like this:
if (myarray.length > 10 && myarray[10] == 5) { /* ... */ }
Here the second condition may only even be evaluated if the first one is true. Thanks to short-circuiting, if the first condition is false the second is never touched.
YES
(AFAIK)
The same things applies to && but in reverse manner.(for first false).
The same rule as in circuits for AND and OR gates.
Yes, it's called short-circuiting. It also will short circuit &&, i.e.
if (a && b && c)
If a is false then the condition cannot be true, neither b nor c are checked.
This can be problematic if you call methods that return booleans. To get around this, you can use bitwise & and |.
Yes it is correct. If you use | this operator to check OR condition then it checks rest all conditions. It also applied on AND(&) operator.
Yes, and one important thing, if you do any operations in the second part, they will not be made. For example:
int a = 5;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 5
//b = 5
BUT in case:
int a = 3;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 4
//b = 5
I tried to make a simple example, but sometimes you call a method in the second part, (which will not be called if first part was true in case of ||), or the first part was false in case of &&

Categories