Why do I get -1 from this statement? - java

if(heading == 2){
nextY = (y-1) % 20;
nextX = x;
}
When debugging this program, my heading is 2 and y = 0, however, when I come to this if statement, nextY becomes -1. Why is it not cycling properly? (0-19)?

That's how mod operation generally works for negative numbers in programming (in all languages I tried it in).
But you can easily make number positive before doing mod
nextY = (y + 20 - 1) % 20;

Modulo operators often return negative numbers for negative inputs. For example, C# will give you a number from -356..359 for the expression x % 360.
Instead of subtracting 1 then taking modulo 20, you can add 19, which is the same thing but keeps the number positive, or you can use the ternary operator:
nextY = (y+19) % 20; // or
nextY = (nextY == 0) ? 19 : nextY - 1;

Related

Calculating the largest int less than the base 2 log of N

I have been reading Algorithms, 4th Edition, and it defines a question as follows:
Write a static method lg() that takes an int value N as an argument and returns the largest int not larger than the base-2 logarithm of N in Java. Do not use Math.
I discovered the following solution:
public static int lg(int N) {
int x = 0;
for (int n = N; n > 1; n/= 2) x++;
return x;
}
I am wondering why that solution works. Why does dividing by 2 continuously allow us to find the largest integer less than the base 2 logarithm of the argument? I do understand Java, just not how this particular algorithm works.
Thank you.
This has to do with properties of exponents and logarithms. The main observation you need is that
2lg n = n,
because logarithms are the inverses of exponentials. Rearranging that expression gives
1 = n / 2lg n.
In other words, the value of lg n is the number of times you have to divide n by two in order to drop it to 1. This, by the way, is a really great intuition to have when studying algorithms, since log terms show up all the time in contexts like these.
There are some other nuances here about how integer division works, but this is the basic idea behind why that code works.
Its follows trivially from the logarithmic identity log(a/b) = log(a) - log(b).
You are searching for the largest integer x so that:
x <= log2(n)
Using the identity above and taking in account that log2(2) = 1 we get:
x <= log2(n/2) + log2(2)
x <= log2(n/2) + 1
x <= log2(n/4) + 2
x <= log2(n/8) + 3
...
x <= log2(1) + k
x <= k (since log2(1) = 0)
So x is the number of times you divided n by 2 before reaching 1.
The answer is purely Mathmatics,
log₂(n) = ln(n)/ln(2) = x
By applying the rules of exponential:
ln(n) = ln(2)*(x)
n = 2^x
Therefore you have to divide by 2 until the value is smaller than 1 in order to get the closest int to it.
We are looking for the largest integer x such that x <= log_2(N) i.e. 2^x <= N
or equivalent 2^x <= N < 2^{x+1}
Let N_0=N
and for k > 0, N_k the quotient of the division of N_{k-1} by 2 and r_k in {0, 1} the remainder (N_{k-1} = 2.N_k + r_k)
We have:
2^{x-1} <= N_1 + (r_1 / 2) < 2^x
But 0 <= r_1 / 2 <= 1/2 and the others numbers are integers so that is equivalent to
2^{x-1} <= N_1 < 2^x
We have successively:
2^{x-1} <= N_1 < 2^x
2^{x-2} <= N_2 < 2^{x-1}
…
2^{x-x} <= N_x < 2^{x-x+1}
The last is also written 1 <= N_x < 2
But N_x is an integer so N_x = 1
Hence x is the number of division by 2 of N remaining greater or equal than 1.
Instead of starting from N_1, we can start from N_0 = N and stay greater than 1.

How do I check divisibility in Java?

I am trying to check if on number is divisible by another, and currently I use this method:
int x = 70;
int y = 30;
if(x/y == Math.round(x/y)) {
...
}
Is there a simpler way?
You can use modulus operator like this in your condition,
if (x%y == 0)
A good way is to use modulus operator, which returns the remainder after dividing by a number, e.g.
5 % 2 = 1 (1 is the remainder after 5 is divided by 2)
So for a number to be divisible by another, it should have a remainder of 0 (i.e. x % y = 0)
if (x % y == 0)
{
//x is divisible by y
}
else
{
//x is not divisible by y
}

Efficient code for checking offset in pixel coordinates

I'm making a tile-based rendering method for a game, using Java.
There is the possibility of the first row (and column) of tiles be partially drawn on screen and i want to know how many pixel of these tiles are on screen.
I came up with this (for checking the max X coordinates of broken tiles):
int brokenX = xOffset; //xOffset can be any number
while (brokenX < 0){
brokenX += tileSet.getTileSize(); //corrects if the number is negative
}
while (brokenX >= tileSet.getTileSize()){
brokenX -= tileSet.getTileSize(); //corrects if the number is too big
}
This works fine. But it seems like a waste of resources (considering it will be done twice for each frame).
Is there some efficient way (bit masks and such) of doing this?
I think you're looking for
brokenX = xOffset % getTileSize();
I think the above should work for negative also but if xOffset can be greater, then you could do
ok.. good. I think just adding a check in the last line should fix it.
hiddenTiles = xOffset / getTileSize();
xOffset -= hiddenTiles * getTileSize();
if(xOffset < 0) {
brokenX= -(-xOffset % getTileSize());
}
else {
brokenX = xOffset % getTileSize();
}
Or as Jason suggests:
Just the one line...
brokenX= (xOffset + getTileSize())% getTileSize());
I really think, this should work for negative offsets also. So no changes are required.
I'd suggest to use a library function. Obviously, it's an huge overkill for this task, but there's much more in a good library. My favorite is Guava and this is the mod method:
int result = x % m;
return (result >= 0) ? result : result + m;
An example should make it clear. I'm trying the numbers 13, 3, -7, -17 modulo 10, which all should return the same result.
13 % 10 = 3, that's OK
3 % 10 = 3, still OK
-7 % 10 = -7 is negative and unusable as index, but with-7 % 10 + 10 = 3 it's fine.
-17 % 10 + 10 = 3 is fine, too.
So for result < 0, or equivalently m < 0, you need to add m to get a positive result.
The following is a common way of overcoming the negative problem in modulo without a conditional:
int tileSize = tileSet.getTileSize();
int brokenX = ((xOffset % tileSize) + tileSize) % tileSize;
int brokenY = ((yOffset % tileSize) + tileSize) % tileSize;
This works since:
The first modulo makes sure that the number is less than tileSize
The addition makes sure that the number is positive, since it was less than tileSize, and was added tileSize
The second modulo makes sure that the number is positive and less than tileSize again
If tile size is a power of two you could do
brokenX = xOffset & (tileSize - 1);
if (brokenX < 0)
brokenX = tileSizeX - (Math.abs(brokenX) % tileSizeX);

Java logical test questions

I've been solving a few problems about logic tests for AP Computer Science but I happened to get stuck on a few questions.
Here are the directions from the website: Translate each of the following English statements into logical tests that could be used in an if/else statement. Write the appropriate logical test for each statement below. Assume that three int variables, x, y, and z, have already been declared.
These are the 2 questions I have problems with:
Either x or y is even, and the other is odd.
x and z are of opposite signs.
I've been trying to find these answers out for a couple of hours and I still have no clue. I would appreciate it if someone could guide me in the right direction. I understand this is "homework" but some definitive help would be very helpful.
For the first question: x % 2 != y % 2
Second question: x * z < 0
You'll need to use and (&&) and or (||) to make a logic formula. I'm not going to do yours, but here's another one:
x is bigger than both y and z or x is less than both y and z.
Translates to:
((x > y) && (x > z)) || ((x < y) && (x < z))
You just need to figure out a formula for odd/even (hint - the low order bit) and for positive/negative (hint - compare with 0), and combine those with and/or.
For the first question, if x (or y)* is odd, y (or x) must be even, and vice versa. Checking for odd values implies that the modulo of x and 2 is 1 - from there, you would have to assert if y (or x) modulo 2 is 0 (to check for evenness).
For the second question, you would need to follow a chain of logic as such:
X is positive (or greater than 0), which implies Z must be negative (or less than 0).
Z is positive, which implies that X must be negative.
*: This is an exclusive or - I mean that you're either checking x or y, but not both at the same time.
First you have to fully understand the statement in order to put it into the language of a computer. For example,
x and y have the same sign
What this really means is:
( x is greater than or equal to 0 and y is greater than or equal to 0 ) or ( x is less than 0 and y is less than 0 )
Now it is easy to put this into Java:
(x >= 0 && y >= 0) || (x < 0 && y < 0)
Of course, your questions can be solved via a similar method.
Either x or y is even, and the other is odd.
The sum of an odd and even number is odd. The sum of two odd numbers is even and the sum of two even numbers are even.
So (x+y)%2!=0.
x and z are of opposite signs
This one is similar, you can do:
x*z<0
Since 0 is neither negative or positive and
neg * pos = neg
neg * neg = pos
pos * pos = pos
If you want to consider 0 and a negative number of opposite signs you can use (x >= 0) == (z < 0)
Putting it in plain english, for me anyhow.
If ((x is even AND y is odd) OR (x is odd AND y is even))
For the other
If ((x gt or eq 0 AND y lt 0) OR (y gt or eq 0 AND x lt 0))
Assuming 0 is positive.

Define range of value

I need to set an int variable in each iteration +-1, the range should be between 0-10. When i add 1 to 10 -> 0 when i add -1 to 0 -> 10. I know i need to go with modulo here but cannot find any solution.
This seems to easy, but if you really want to use modulo, did you try;
x = (x + y) % 11;
if (x < 0) x += 11;
or for "ultimate readability" and probably still better performance just
x = x + y;
if (x < 0) x += 11;
if (x > 11) x -= 11;
Please note that the requirements locks y down to being -1 or 1.

Categories