I have learned a lot from my last question hopefully I don't make the same mistakes again:)
This stems from a previous question. Here is what I THINK I know:
For ints in java (I assume in all languages but I’m asking in JAVA specifically):
1/3 = 0
1%3 = 1
I was stumped as to why i%j = i when i < j and a previous poster explained how this worked and also stated that "First, in Java, % is the remainder (not modulo) operator, which has slightly different semantics...."
Their explanation was perfect for what I needed. However, I was confused by their quote because I was always taught that in mathematics modular == remainder division.
How does one execute modular division in JAVA and are there pitfalls to watch for when trying to use % as a modulus operator?
mathematicaly, modulo is division with remainder.
7 mod 4 = 1 R3
see:
n = a * m + r
The modulo operator in Java (like in most other languages) gives only the remainder part and not i dont know, if it works with negative numbers correct.
In Detail, mathematicaly the modulo is allways positive. That is the differece to the modulo operator in java.
a mod n = b, if there is a number k existing with a = b + kn
and 0 <= b < n
That means, if you take -14 mod 4:
-14 = b + k * 4 //lets take -3 for k
-14 = b + -3 * 4
-14 = b - 12
-2 = b
that would be wrong (mathematically) becaouse b is negative.
so we need to take -4 for k
-14 = b + -4 * 4
-14 = b + 16
2 = b
that is the correct answer. In this case only the sign is the difference, but if you take -15 mod 4 you will get -3 in java and most other languages, but the mathematically correct answer would be 1 (-15 + 16)
using java, you will get the negative values.
You may be confused by the "modulo operator" in arithmetic, which is the same as the % operator in Java and similar languages, I don't think there is such thing as "modular division". The % operator in java will always return the integer remainder from repeated division between two numbers. Just like in arithmetic, (i % j) = i where i < j and i >= 0. The result of the operation is less than j.
Related
In java when you do
a % b
If a is negative, it will return a negative result, instead of wrapping around to b like it should. What's the best way to fix this? Only way I can think is
a < 0 ? b + a : a % b
It behaves as it should a % b = a - a / b * b; i.e. it's the remainder.
You can do (a % b + b) % b
This expression works as the result of (a % b) is necessarily lower than b, no matter if a is positive or negative. Adding b takes care of the negative values of a, since (a % b) is a negative value between -b and 0, (a % b + b) is necessarily lower than b and positive. The last modulo is there in case a was positive to begin with, since if a is positive (a % b + b) would become larger than b. Therefore, (a % b + b) % b turns it into smaller than b again (and doesn't affect negative a values).
As of Java 8, you can use Math.floorMod(int x, int y) and Math.floorMod(long x, long y). Both of these methods return the same results as Peter's answer.
Math.floorMod( 2, 3) = 2
Math.floorMod(-2, 3) = 1
Math.floorMod( 2, -3) = -1
Math.floorMod(-2, -3) = -2
For those not using (or not able to use) Java 8 yet, Guava came to the rescue with IntMath.mod(), available since Guava 11.0.
IntMath.mod( 2, 3) = 2
IntMath.mod(-2, 3) = 1
One caveat: unlike Java 8's Math.floorMod(), the divisor (the second parameter) cannot be negative.
In number theory, the result is always positive. I would guess that this is not always the case in computer languages because not all programmers are mathematicians. My two cents, I would consider it a design defect of the language, but you can't change it now.
=MOD(-4,180) = 176
=MOD(176, 180) = 176
because 180 * (-1) + 176 = -4 the same as 180 * 0 + 176 = 176
Using the clock example here, http://mathworld.wolfram.com/Congruence.html
you would not say duration_of_time mod cycle_length is -45 minutes, you would say 15 minutes, even though both answers satisfy the base equation.
Java 8 has Math.floorMod, but it is very slow (its implementation has multiple divisions, multiplications, and a conditional). Its possible that the JVM has an intrinsic optimized stub for it, however, which would speed it up significantly.
The fastest way to do this without floorMod is like some other answers here, but with no conditional branches and only one slow % op.
Assuming n is positive, and x may be anything:
int remainder = (x % n); // may be negative if x is negative
//if remainder is negative, adds n, otherwise adds 0
return ((remainder >> 31) & n) + remainder;
The results when n = 3:
x | result
----------
-4| 2
-3| 0
-2| 1
-1| 2
0| 0
1| 1
2| 2
3| 0
4| 1
If you only need a uniform distribution between 0 and n-1 and not the exact mod operator, and your x's do not cluster near 0, the following will be even faster, as there is more instruction level parallelism and the slow % computation will occur in parallel with the other parts as they do not depend on its result.
return ((x >> 31) & (n - 1)) + (x % n)
The results for the above with n = 3:
x | result
----------
-5| 0
-4| 1
-3| 2
-2| 0
-1| 1
0| 0
1| 1
2| 2
3| 0
4| 1
5| 2
If the input is random in the full range of an int, the distribution of both two solutions will be the same. If the input clusters near zero, there will be too few results at n - 1 in the latter solution.
Here is an alternative:
a < 0 ? b-1 - (-a-1) % b : a % b
This might or might not be faster than that other formula [(a % b + b) % b]. Unlike the other formula, it contains a branch, but uses one less modulo operation. Probably a win if the computer can predict a < 0 correctly.
(Edit: Fixed the formula.)
I am trying to understand how java.util.Random.nextInt(int n) works and despite all the search and even debugging cannot completely understand the implementation.
It is the while loop that causes confusion:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int)
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
I realize this is supposed to address the modulo bias, but struggling to see how.
Question: how can possibly the expression
bits - val + (n-1)
be negative given that bits value is 31 bit long, i.e. bits is always positive? If bits is positive, val is always less than bits then while condition always stays > 0...
The question has been already addressed in implementation-of-java-util-random-nextint.
Basically, we have to drop some top-most elements for bits in the range [0..2^31[ because they induce a non-uniform distribution
Mathematically we check :
bits - val + (n-1) >= 2^31
and could have wrote it as is if java had unsigned 32 bits integer arithmetics.
You are missing the value of n in your calculation. Either n is negative, bits - val -1 1 < n or otherwise N is big enough to make the integer overflow and become a negative number.
I am trying to calculate the value of (10^5.102103)%24 that is 10 raised to power 5.102103 modulus 24 in Java ?
Which is the best and accurate method to do because
int a;
double b;
int m;
Calculate (a^b)%m
Where a can be very large like upto 10^9
b can be any double or float value which can be large
and m is any Integer
Example ---How you can calculate the value of
(10^10002.3443)%10000007
I know Math.pow(a,b) function works for small a and b only
While BigInteger function Uses only modPow(a,b) where a and b should be integer only(Correct me if i am wrong)
Unfortunately, it's not possible using the normal Java data types to get a correct answer to this. If you use double to store the exponent, you introduce an error, because double won't store most decimal numbers exactly. When you write double b = 10002.3443; the number that is stored in b is actually 10002.34430000000065774656832218170166015625. Even though it looks like 10002.3443 when you print it, that's a trick of the way Java prints numbers - basically it chooses the decimal number with the least number of decimal places that would be represented by that double.
Now this difference looks insignificant. But the difference between 10^10002.3443 and 10^10002.34430000000065774656832218170166015625 is approximately 3.346 x 10^9990, which is a 9991-digit number. Now, what will this difference become when we apply the modulus operator?
(10^10002.34430000000065774656832218170166015625 % 10000007) - (10^10002.3443 % 10000007)
= (10^10002.34430000000065774656832218170166015625 - 10^10002.3443) % 10000007
= (3.346 x 10^9990) % 10000007 (approximately)
Now, it's anybody's guess what that actually comes to. But you've got a better chance of being struck by lightning than of getting the correct answer, if you use double at any point in the calculation.
The other option might be BigDecimal. But the problem is that 10^10002.3443 is irrational - it's not a terminating decimal, so it can't be represented correctly in a BigDecimal.
So Java doesn't have a data type that will allow you to perform the calculation that you want to perform.
You are going to have to invent your own data type, then work out how to do all the bit-crunching to implement exponentiation and modulus. This is a huge project, and I suggest you start out by getting yourself a PhD in mathematics.
(Note: Obviously, I am using ^ to indicate exponentiation and x to indicate multiplication in the above, even though this is not the normal Java convention)
Let's think back to discrete math!
Given y = a b (mod m), we know that
y = ((a mod m)^b) mod m
For example, if we have
a = 2, b = 6, m = 5
a raised to the power of b is 64. 64 mod m is 64 % 5 == 4. Let's check our algorithm:
4 == ((a mod m)^b) mod m
4 == ((2 mod 5)^6) mod 5
...
4 == 64 % 5
4 == 4
This doesn't really help us all too much (in its current form), so let's use modular arithmetic at every step to save the day.
int a = 10;
int m = 10000007;
double b = 10002.3443;
int holder = (int) b;
double delta = b - holder; // as close as we're going to get
int total = 1;
for (int i = 0; i < holder; i++) {
total *= (a % m); // multiply by the modulus
total %= m; // take the modulus again
}
total *= (Math.round(Math.pow(a, delta)) % m);
total %= m;
Here is my FIRST Question
Here is my code:
public class Bits{
public static void main(String args[]){
int i = 2 , j = 4;
int allOnes = ~0;
int left = allOnes << (j+1);
System.out.println("Binary Equivalent at this stage: " +Integer.toBinaryString(left));
}
}
The following is the output I'm getting:
Binary Equivalent at this stage: 11111111111111111111111111100000
How can I restrict it to only 8 bits from the right hand side. I mean 11100000 .
Please explain.
Here is my SECOND Question:
Also, I have one more Question which is totally different with the above one:
public static void main(String args[]){
int i = 2 , j = 4;
int allOnes = ~0; // will equal sequence of all 1s
int left = allOnes << (j+1);
System.out.println("Binary Equivalent at this stage: " +Integer.toBinaryString(left));
}
}
Since I didn't understand the following line:
int allOnes = ~0; // will equal sequence of all 1s
When I tried to output the value of "allOnes" then I got "-1" as my output.
I'm having hard time understanding the very next line which is as follows:
int left = allOnes << (j+1);
int allOnes = ~0;
Takes the integer 0 and applies the NOT operation bitwise so it will have all ones in its binary representation. Intagers use the two's complement format, meaning that a value of a word having all bits as one is value of -1.
If you only care about byte boundaries, then use a ByteBuffer
byte lastByte = ByteBuffer.allocate(4).putInt(i).array()[3];
To restrict this byte to the first four or last four bits, use lastByte & 0b11110000 or lastByte & 0b00001111
The integer representation of -1 is all 1's, i.e. 32 bits all set to 1. You can think of the first bit as -2^31 (note the negative sign), and of each subsequent bit as 2^30, 2^29, etc. Adding 2^0 + 2^1 + 2^2 ... + 2^30 - 2^31 = -1.
I suggest reading this tutorial on bitwise operations.
For #1 Integer.toBinaryString(left) is printing 32 bits (length of Integer), so if you just want the right 8 you can do the following:
Integer.toBinaryString(left).substring(24)
The ~ operator in Java inverts the the bit pattern. Thus 0 turns into ffff.
The << operator shifts the bits by x. You are shifting the bits to the left by 5 so you end up with 5 zeros on the right.
Here are all the bitwise operators for Java
First, a more general solution for the first question than what I've seen so far is
left &= (2 ^ n) - 1;
where n is the number of binary digits that you want to take from the right. This is based around the bitwise AND operator, &, which compares corresponding bits in two numbers and outputs a 1 if they are both 1s and 0 otherwise. For example:
10011001 & 11110000 == 10010000; // true
This is used to create what are known as bitmasks (http://en.wikipedia.org/wiki/Mask_(computing)). Notice how in this example how the left 4 bits of the first number are copied over to the result and how those same 4 bits are all ones in the second number? That's the idea in a bit mask.
So in your case, let's look at n = 8
left &= (2 ^ 8) - 1;
left &= 256 - 1;
left &= 255; // Note that &=, like += or *=, just means left = left & 255
// Also, 255 is 11111111 in binary so it can be used as the bitmask for
// the 8 rightmost bits.
Integer.toBinaryString(left) = "11100000";
Your second question is much more in depth, but you'd probably benefit most from reading the Wikipedia article (http://en.wikipedia.org/wiki/Two's_complement) instead of trying to understand a brief explanation here.
8 bits in decimal has a maximum value of 255. You can use the modulo (remainder) division operator to limit it to 8 bits at this point. For isntance:
int yournum = 35928304284 % 256;
will limit yournum to 8 bits of length. Additionally, as suggested in the comments, you can do this:
int yournum = 3598249230 & 255;
This works as well, and is actually preferred in this case, because it is much faster. The bitwise and function returns 1 if both associated bits are 1; since only the last 8 bits of 255 are one, the integer is implicitly limited to 255.
To answer your second question: A tilde is the bitwise inversion operator. Thus,
int allOnes = ~0;
creates an integer of all 1s. Because of the way twos complements works, that number actually represents -1.
I am new to Java, actually programming in general. I understand that the modulus operator (%) returns the remainder of two numbers, however, I do not understand why 17 % 40 = 17.
I understand that 40 % 17 = 6, and 17 % 5 = 2, and 40 % 5 = 0. I get the gist of what value is returned as the remainder. But 17 % 40 = 17 has me stumped.
The only rationalization I can devise is that since the remainder is less than 1 the total value 17 is returned, why not 0? Please help to explain this enigma to me.
When you divide 17/40, quotient is 0 and the remainder is 17.
The modulo operator (%) returns the remainder.
i.e
a % b = remainder of a / b
Equation from Wiki by Knuth:
a = 17
n = 40
floor(a/n) = 0
so r = 17
When n > a then r is simply a.
i guess learning back the 3rd and 4th standard maths is the key point.
if u see (hope understand the division syntax. its the popular 3rd std way )
____
40)17
you will get a reminder 17 as 17 is not divisible by 40.
then there will be an adition of '.' and then the fraction will be added
If you have the numbers a and b, their quotient q and remainder r, then the following has to be true:
q · b + r = a
That is, if you multiply the quotient (q) by the divisor (b) and add the remainder (r), the result is the dividend (a).
In your case a = 17, b = 40, q = 0 and so r has to be 17.
Note: the equation above is just a rearrangement of the equation from Nikolay Kuznetsov's answer, but I think it's easier to understand this way.
Maybe this is a different and more helpful way to think about it.
When we apply division to integer numbers a and b, we are really trying to relate a and b like this:
a = Q * b + R
a is some multiple of b, plus some leftover. Q and R are integers; to keep this simple, let's also just think of non-negative numbers. The multiple, Q, is the quotient and leftover, R, is the remainder -- the smallest ones that make this relation work.
In most languages, a / b gives you Q, and and a % b gives you R. (In fact processors tend to compute both at once -- these are so related.)
So if a is 17 and b is 40, it only works if you write:
17 = 0 * 40 + 17
This is why a % b must be 17.
(Note that it gets more complex when considering negative numbers.)