Is there any math utility method to calculate the following expression? Basically, I need to find the largest integer less than or equal to x which can be divided by N evenly.
x - x % N; // N is an integer.
For positive integers: (x / N) * N.
(If it needs to be strictly less than x vs <= x then use ((x-1)/N) * N, for x > 0.)
if x is a positive integer and N a power of 2 you can do x & -N
EDIT: its -n not 2-n , thanks to Peter Lawrey for pointing that out
If x is a positive integer then you can use
int result = x - x % N;
or
int result = (x/N)*N;
If x is a positive double then you can use
int result = N * (int)(x/N);
Related
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.
I am trying to solve a problem that I need to get value of three unknowns(x,y,z) knowing some info. their summation is equal to 70, x^2 + y^2 = z^2 and x < y < z.
Answer should be x = 20, y = 21, z = 29
I tried to solve it as two equations in three unknowns but I failed. Any hints to get the solution ? I want to find an algorithm or equation to build a java code that solve this problem
I'll assume that x, y, and z must be positive integers, since removing the integers restriction allows infinitely many solutions. Here is an algorithm--I'll leave the code to you.
Your second equation x^2 + y^2 = z^2 means that x, y, and z form a Pythagorean triple. All solutions to that equation have the form
x = k(m^2 - n^2), y = 2kmn, z = k(m^2 + n^2)
(with possibly x and y swapped) where m, n, and k are positive integers, m > n, one of m and n is even and the other is odd, and (m, n) are relatively prime. You can drop those last two restrictions on m and n, which is to make the triples have unique representation.
Your third limitation x < y < z merely makes a unique triple from the three values. Importantly, your first restriction x + y + z = 70 means that your solution has "small" values.
So in your code, vary the three parameters k, m, and n. There are only finitely many values that allow the sum of x, y, and z to be less than or equal 70, which places limits on k, m, and n. Find the ones that equal make the sum of x, y, and z to be 70. You can cut the number of trials in half by not letting m and n be both even or both odd. You can also avoid explicitly varying k by varying only m and n and calculating what k should be, since each of x, y, z vary proportionally with k, and accept only integral k.
This is somewhat of a brute-force solution, but it is easy to program and will be faster than just trying all values of x, y, and z.
EDIT: I now see that x, y, and z may also be zero. That theoretically means that you need to test for x = 0, but that is clearly impossible here since then y^2 = z^2 which contradicts y < z. So no change is needed to my algorithm.
Expanding on #RoryDaulton's answer, taking x = k(m^2 - n^2), y = 2kmn and z = k(m^2 + n^2) and applying the sum constraint gives us
2*k*m*(m + n) = 70
Or
k * m * (m + n) = 35 = 7 * 5 = 35 * 1
The important thing to note is that the RHS of the above has only two unique factors; the LHS has three. Thus at least one factor of the LHS (k, m, m + n) must be 1.
Since m and n are unique positive integers, m + n will always be greater than 1. Thus,
k = 1 or m = 1
And the only possible values for the remaining LHS factors are 7 and 5 or 35 and 1.
This makes the problem much easier to brute force.
I have solved the question and I want to thank all people who helped me.
This is My code to solve the problem
int x,y,z;
long mul=0;
for(int n=1;n<=sum;n++){
for (int m=2;m<=sum;m++){
x= (int) ((Math.pow(m,2)) - (Math.pow(n,2)));
y= 2*m*n;
z= (int) ((Math.pow(m,2)) + (Math.pow(n,2)));
if(x+y+z == sum){
mul = x*z*y;
}
}}
return mul; }}
I was checking some code online when i found the following statement
number /= 10;
I know that / mean divison and = is the assignment operator but i don't understand what it does in this case.
It is equivalent of -
number = number / 10;
It is a composite operator - consist of division and assignment. You may found something like this -
+=
-=
%= etc.
All of these above works similarly.
It means that whatever the value number contains will be divided by 10 and the result will be stored back into number.
It is exactly equivalent to
number = number / 10
Most of the major operators have it:
number *= 10
number += 10
number -= 10
number %= 10
number >>= 10
number <<= 10
It means
number =number/10;
Number divided by 10
you can also do
number operator=number
where operator can be +,/,*
This is the shorter notation for number = number / 10;
The same exists for the other operators as well:
x += y; => x = x + y;
x -= y; => x = x - y;
x *= y; => x = x * y;
x %= y; => x = x % y;
I'm stuying this code and I don't understand what this line does: [(y << 3) + x]
for (int y = 0; y <= 7; ++y) {
for (int x = 0; x <= 7; ++x) {
final String pieceCode = pieceCodes[(y << 3) + x];
if (pieceCode.length() != 2) throw new IllegalArgumentException();
if (!pieceCode.equals("--")) {
pieces[((7 - y) << 3) + x] = CheckersPiece.valueOf(pieceCode.charAt(0), pieceCode.charAt(1));
}
}
}
It's an obfuscated way of multiplying by 8. Thus, (y << 3) + x is equal to 8 * y + x.
The reason that y << 3 is equivalent to multiplying by 8 is because << is the left-shift operator: it shifts all the bits of y left by one position. In the same way that if you take a base-10 number and shift left by one position you have multiplication by 10, shifting left in base-2 is equivalent to multiplying by 2. Therefore, shifting left by three positions is equivalent to multiplying by 2 * 2 * 2 = 8. In general, shifting left by n positions is equivalent to multiplying by 2^n (as long as you don't have bits falling off of the left end).
In the olden days, programmers wrote code like this because left shifts are super duper fast, faster than multiplication and so 8 * y was less optimal than y << 3. But these days, compilers are pretty good at figuring out when to replace something like 8 * y with y << 3.
Therefore, I say it's obfuscated because 8 * y more clearly expresses the intent: the intent of (y << 3) + x is to skip by y blocks of 8, and take the xth position in that block. And this is much more clearly expressed by saying 8 * y + x. Remember, we code in high-level languages for humans to read and understand the code. Our code should be written for the humans. The compiler can do its job of making good machine instructions for the machine to understand.
It's done this way because it's trying to pretend that pieceCodes is a 2D array, just mapped into a 1D array.
That is, piecesCode looks like this
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
but we can pretend it looks like this
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
See, given (x, y) -> 8y + x we accessing the xth column, yth row of piecesCode. That is, y tells us how many blocks of 8 to skip, and x tells us where to go within that block.
(y << 3) means bit shifting 3 times to the left. It's the same as multiplying by 2^3 = 8. So, whole expression (y << 3) + x becomes y * 8 + x.
It should be written in the form y * 8 + x, because it's more readable and very probably there is no performance gain. Premature optimization is the root of all evil. It's better to left such micro optimizations to the compiler (or JVM).
Moreover, board size could be stored in a constant, to have it only in one place:
final int SIZE = 8;
// ...
for (int y = 0; y < SIZE; y++) {
for (int x = 0; x < SIZE; x++) {
final String pieceCode = pieceCodes[y * SIZE + x];
y * 8 + x is just iterating over a (logically) 2D table with 8 rows and columns, stored as 1D, with 64 cells.
As a final remark, I would like to point out, that in the given code pieceCodes is an array of Strings...
But in fact, it's an array of piece codes. Not just some Strings. Now, "--" works as some magic state and nobody except the programmer knows, what it means. if (pieceCode.length() != 2) also looks bad. So, there should be an object PieceCode and array will be declared as PieceCode[] pieceCodes. In PieceCode we can implement proper equals() method. If PieceCode is only a state, it can be an Enum. For example EMPTY, WHITE_PAWN, WHITE_QUEEN, BLACK_PAWN, BLACK_QUEEN. Comparing Strings is not as fast as comparing Enums. We also have to watch out to write equals(), instead of ==.
From the spec:
The value of n << s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.
<< and >> are bit shift operators. In this case, it converts y to binary and "shifts" over 3 places, adding new bits to the end as required
For example, if y was 8, it would have the value of 1000
y<<3 would shift to the left 3 bits, resulting in 1000000, or 64
That is called a bitwise and bit shift operator. Also, check out the wiki.
Summary of the documentation
The Java programming language also provides operators that perform bitwise and bit shift operations on integral types. The operators discussed in this section are less commonly used.
The unary bitwise complement operator "~" inverts a bit pattern. The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right.
The bitwise & operator performs a bitwise AND operation.
The bitwise ^ operator performs a bitwise exclusive OR operation.
The bitwise | operator performs a bitwise inclusive OR operation.
Example code:
class BitDemo {
public static void main(String[] args) {
int bitmask = 0x000F;
int val = 0x2222;
// prints "2"
System.out.println(val & bitmask);
}
}
So... What is a bitwise and bit shift operator?
In order to save time and space, I'll simply include this article explaining all operators in depth!
The code uses an optimization technique that represents a two dimensional array[m][n] as a one dimensional array[m*n]. Both m and n appear to be 8 here (8-queens, chess, maybe?).
The trick is to transpose index tuples (i,j) to indexes for the one dimensional array.
Most of the time, you do this by multiplying i with n and add j.
Since n=8, multiplication can be expressed in this case by shifting 3 bits left. This conveys the message "We are doing adress arithmetic here on some nicely sized (i.e. in terms of power of 2) arrays.", at least to the non-novices.
Quick answer, it's an efficient way of multiplying a number by 8 (2^3=8)
y << 3 means "shifted 3 bits left" ... which is, essentially, another way to do "* 8"
If you do a right-shift (y >> 3), that would be integer divide by eight, but is also useful because the bits fall off the end, and you sort of "drain" the bits if you loop.
It used to be (way way back when) that CPU shift was faster than multiplication, so using "x << 1" was faster than "x * 2". However, that's not true anymore.
I used to see expressions in code like "x << 4 + x << 2 + x << 1" ... which is really "x * 16 + x * 4 + x * 2" or "x * 22".
http://en.wikipedia.org/wiki/Bitwise_operation ... In Java, all integer types are signed, and the "<<" and ">>" operators perform arithmetic shifts. Java adds the operator ">>>" to perform logical right shifts, but because the logical and arithmetic left-shift operations are identical, there is no "<<<" operator in Java.
I want to get the value of an unknown number in equation containing modulus % in Java
For example:
x % 26 = y if I have the value of y how can I get x
The problem is that there are either zero solutions (if Math.abs(y) >= 26) or an infinite1 number of values of x that satisfy that equation for a given y. The general answer is:
x = 26 * k + y
for any integer value of k. You can pick whatever k you want.2
1 In practice, the range will be limited by the range of integer values you are using. If x and y are int values, then you are limited by Integer.MAX_VALUE and Integer.MIN_VALUE. On the other hand, if they are BigInteger values, you don't have much in the way of range constraints.
2 Actually, the signs of x and y must be the same in Java, so you only have half of infinity to pick from. :-)
You can't get the value of x, that's how modulus works. You just know x = 26 * k + y where k is an integer.