To reverse an integer and put it into a list, one would do the following (where x is some integer):
int lastDigit = x;
while(lastDigit != 0)
{
list.add(lastDigit % 10);
lastDigit /= 10;
}
So if x was 502, 2 0 and 5 would get added to the list.
This is obviously really useful, but until yesterday I thought the only way to do something like this was by converting the int to a string first.
I'm not sure if this is just common knowledge but I had not seen this method before today. I would like to understand how it works instead of merely memorizing it.
Could someone explain why the number modulus 10 gives the last digit, and why dividing it by 10 gives the next digit on the next iteration? Why would it eventually equal 0?
The modulus operator gives you the remainder from doing a division calculation.
502 % 10 is 2 because 502/10 = 50 plus a remainder of 2.
Therefore the remainder in this calculation is 2, meaning 2 will be added to the list.
The division by ten in the next line is performed using integer arithmetic, so 502/10 gives a result of 50.
Any non-negative number less than 10 will give a result of zero, ending the loop.
Think of % 10 as getting the least significant (right most) digit in decimal system (hence 10).
And then think of / 10 as shifting all digits one place right (also decimal). You obviously have to do it until the number is 0. All remaining digits can be understood as leading zeros in this case.
In binary system you can also use the bitwise operations & 1 and >> 1 instead of modulo (% 2) and integer (/ 2) divisions.
The list append operation (here add) is the one that reverses the order. The operations above are just for extraction of the single digits.
Related
Currently I am working with the % operator in Java. I thought I understood it but after coming across this question am now confused. So I know that 10 % 3 = Remainder 1. My question is why would 3 % 8 = Remainder 3 I thought that this would instead equal 0 because 3 goes into 8 zero times? Another example would be 2 % 8 = Remainder 2 why would this ones remainder not be zero also? If someone could explain why this is that would be awesome! Thank you!
The remainder operator is explained in the Java tutorial at https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op1.html
If you are looking for a modulo operator, then use Math.floorMod at it treats negative numbers as you'd expect. The documentation gives examples of the difference between % and floorMod: http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floorMod-int-int-
This is the correct behavior, mathematically speaking.
Hopefully people will indulge me a digression, but the integers mod n are all of the integers from 0 to n - 1. They form a multiplicative group that's important to number theory and cryptography. In fact, if you do
for (int i = 0; i < x; i++) {
Console.WriteLine(i % n);
}
this will give you all the numbers from 0 to (n - 1) over and over again, just like the group.
Without going into details, a mathematical group is a set with an operation that behaves more or less like you'd expect it to with "ordinary" arithmetic. For example, if a set forms a group under multiplication, that means that multiplication "works" for that set.
If n is the power of a prime (e.g. 32), then the integers mod n form a finite field, meaning that it behaves quite a bit like ordinary arithmetic.
TL;DR This behavior is by design. It's actually mathematically perfectly correct as well.
This question already has answers here:
n & (n-1) what does this expression do? [duplicate]
(4 answers)
Closed 6 years ago.
I saw this efficiently written code at Leetcode.com
public static boolean isPowerOfTwo(int n) {
return n>0 && ((n&(n-1))==0);
}
This works awesomely fine but I am not able to figure out the working of single '&' in the code.
Can some onetake efforts to explain how the code works?
And by the same logic what would eb the code to determine if an integer is power of 3?
The single & is a bitwise 'and' operator (as opposed to &&, which acts on booleans).
So when you use & on two integers, the result is the logical 'and' of their binary representations.
This code works because any power of 2 will be a 1 followed by some number of 0s in binary (eg, 4 is 100, 8 is 1000, etc). Any power of 2, less one, will just be all 1s (eg. 3 is 11, 7 is 111).
So, if you take a power of 2, and bitwise and it with itself minus 1, you should just have 0. However, anything other than a power of 2 would give a non-zero answer.
Example:
1000 = 8
0111 = 7 (8-1), and '&'ing these gives
0000 = 0
However, if you had something like 6 (which isnt a power of 2):
110 = 6
101 = 5 (6-1), and '&'ing these gives
100 = 4 (which isnt equal to 0, so the code would return false).
I hope that makes it clear!
The & in Java is a bitwise and operator. It takes two integers and performs an and operation on each bit, producing an int where each bit is set to '1' if and only if that bit was '1' in both operands. The code uses the understanding that any power of two in binary is a '1' followed by some number of '0's. This means that subtracting one will change ALL the bits of the number. For any non power of two, there will be at least one nonzero digit after the first, so the first digit will remain the same. Since performing an AND on two different values always produces '0', ANDing the original number and itself minus one will produce 0 if and only if that number is a power of two. Because this is a trick with binary number specifically, it wouldn't work for finding powers of other bases.
To understand how this function works you need to understand how binary numbers are represented. If you don't I suggest reading a tutorial such as Learn Binary (the easy way).
So say we have a number, 8, and we want to find out if it's a power of two. Let's convert it to binary first: 1000. Now let's look at 8-1 = 7's binary form: 0111. The & operator is for binary AND. When we apply the AND operator to 8 and 7 we get:
1000
0111
&----
=0000
Every integer which is a power of 2 is a 1 followed by a non-negative amount of zeroes. When you subtract 1 from that number you will always get a 0 followed by a sequence of 1s. Since applying the AND operation to those two numbers will always give you 0, you can always verify if it's a power of 2. If the number is not a power of 2, when you subtract 1 from it it won't invert all of its digits and the AND test will produce a positive number (fail).
Its an bitwise operator :
if we take 2 exponent 3 equals to 8,
e.g 2³ = 2×2×2 = 8
now to calculate if 8 is a power of 2, it works like this:
n&(n-1) --> 8 AND (8-1) --> 1000 AND 0111 = 0000
thus it satisfies the condition --> (n&(n-1))==0
The single "&" performs a bitwise AND operation, meaning that in the result of A & B with A and B being integers only those bits will be set to 1 where both A and B have a 1.
For example, lets look a the number 16:
16 & (16 - 1) =
00010000 &
00001111 =
00000000
This works for powers of two because any power of two minus one will have all lower bits set, or in other words n bits can express n different values including zero, therefore (2^n)-1 is the highest value that can be expressed in n bits when they're all set.
I hope this helps.
Powers of three are a bit more problematic as our computers don't use ternary numbers. Basically a power of three is any ternary number that only has one digit different from zero and where that digit is a "1" just like in any other number system.
From the top of my head, I can't come up with anything more elegant than repeatedly doing modulo 3 until you reach one as a division result (in which case you'd have a power of three) or a nonzero modulo result (which would mean it's not a power of three).
Maybe this can help as well: http://www.tutorialspoint.com/computer_logical_organization/number_system_conversion.htm
I need to find out if int n is a power of two and my approach is to convert n to a hex number and check each bit (0 or 1). However, I've never used hex numbers in Java, could anyone help me out here?
Both converting to a String and replacing using a regular expression is expensive.
A simple way to check for a (positive) power of two is to check the number bits set.
if (x > 0 && Long.bitCount(x) == 1)
While Long.bitCount looks complicated, the JVM can replace it with a single machine code instruction.
The canonical way (which you will encounter a lot when googling how to test for powers of two, and you will probably encounter it in code) to test for powers of two is
x != 0 && (x & x - 1) == 0
It is often encountered with more parenthesis (precedence paranoia?)
x != 0 && (x & (x - 1)) == 0
It is common to skip the x != 0 check and guarantee zero can't be an input, or (often enough) zero is "as good as" a power of two in some sense.
You can of course change the condition to x > 0 if you don't want to consider -2147483648 a power of two, though in many cases it would be (because it's congruent to 231 modulo 232, so interpreted unsigned it's a PoT, and anyway it only has one bit set so it was a PoT all along)
So what's the deal with x & x - 1. It unsets the lowest set bit, but let's look at it in the context of PoTs.
Let's ignore x<2 and say x has the form a10k (ie an arbitrary string of bits followed by a one followed by k zeroes), subtracting 1 from it gives a01k because the -1 borrows through all the trailing zeroes until it reaches the lowest set bit, unsets that bit, then the borrow dies and the top bits are unchanged.
If you take the bitwise AND of a10k and a01k you get a00k because something ANDed with itself is itself again (the a), and in the tail there's always a 0 involved in the AND so it's all zeroes.
Now there are two cases. 0) a=0. Then the result is zero, and we know we started out with x of the form 10k which is a power of two. And 1) a!=0, then the result isn't zero either because a still appears in it, and x wasn't a power of two because it has at least two set bits (the lowest set bit which we explicitly looked at, and at least one other somewhere in a).
Well actually there are two more cases, x=0 and x=1 which were ignored. If we allow k to be zero then x=1 is also included. x=0 is annoying though, in x & x - 1 there is that x as the left operand of &, so the result must be zero no matter what happens in the right operand. So it falls out as a special case.
There is no reason to convert to hex to check bits. In fact, that actually makes it harder. The following line produces a binary String for an int variable "num":
String binary = Integer.toString(num, 2)
That String will only have 1s and 0s in it. Then eliminate any 0s:
String ones = binary.replace("0", "");
If the length of the String is more than one, there there is more than one bit, which means it is not a power of 2. If the length is 0, it means the number had no bits, which means it is 0.
in this simple code i can not get Long larger than 1000000000. lenght of that is 10 char and i want to get larger than such as 15 character.
long value = nextLong(rand,1000000000);
long nextLong(Random rng, long n) {
long bits, val;
do {
bits = (rng.nextLong() << 1) >>> 1;
val = bits % n;
} while (bits-val+(n-1) < 0L);
return val;
}
Your long constant is missing an L suffix:
long value = nextLong(rand,100000000000000L);
I want to get larger than such as 15 character.
Java's long has range of –9223372036854775808 to 9223372036854775807 (18 full digits + top digit in the range 0..8), which is sufficient to cover the range that you need to cover. If you need 19 decimal digits or more, you would need to use BigInteger.
You should be able to use BigInt.
Import using:
import java.math.BigInteger;
declare like this:
BigInteger myBigInt = new BigInteger("123456789123456789");
Increase your limit value of 'n'. Since you are limiting the generated random value by performing a modulo 'n', obviously the generated value needs to be less than 'n'. Since your limit is a long, you can increase that limit to allow for 15 digit results without other changes.
However I am not sure what you are trying to accomplish with the loop in the nextLong function. It will only loop when bits > ( Long.MAX - n + 1 ).
I get the feeling that you're limiting yourself by your own modulo operation.
Remember that modulo division is the same as short division - the kind we used back in third grade. That is, instead of dividing out the entire number, we take the whole portion and the remainder.
So, let's take a simple example (a power of 10, since you're using one as well):
99 / 10 = 9 remainder 9
That is to say, if I divide 99 into 10 using short division, I will be able to divide it evenly 9 times, with 9 bits left over. Notice that the left-over is an order of magnitude shorter of what I'm dividing into.
This scales up with higher orders of divisors:
999 / 10 = 99 remainder 9
9999 / 10 = 999 remainder 9
99999 / 10 = 9999 remainder 9
...and so forth. Notice that our remainder is always an order of magnitude below our dividend. This makes sense, since if it were larger than our dividend, it'd be another value we could add to the quotient, and not the remainder.
Now, we come back to your example. You're taking a long value, which can be several orders of magnitude larger or smaller than your passed in value of a billion (which fits fine into an int, and is promoted to a long when you call your method).
The ultimate issue comes down to this:
val = bits % n;
...where bits is some arbitrary long value that could be greater than n.
Remember what we discovered above with the short division above? That's right - your resulting val will be an order of magnitude below your n value - that is to say, it will never be larger than or equal to n.
I'm not entirely sure what it is you're trying to accomplish, so I don't have The Right Thing™ for you to do. But I'd recommend that you re-evaluate the purpose of that modulo operation.
I am trying to create a simple function that utilizes modular arithmetic. This is essentially a number line that wraps around. Specifically I want to use a Mod 8 number line in Java.
What I want is to compare two numbers between 0 and 7. I want to subtract these numbers to get a difference score. However, instead of 0-7=-7, I want it to equal 1. The idea being that after you reach 7, the number line wraps around back to 0 (therefore 0 and 7 are only one space across.)
Are there any packages that fit this criterion?
how about ((0-7)+8) % 8 ? This should fix up your case.
Note: % is the Modular operator.
It appears you want to reverse what negative numbers do with modulos. Keep in mind that the modulus is the remainder after integer division. Normally you would have a range that looks like this:
-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
You want it to look like this for the same series of values:
1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
If you want to solve for the general case where you can have any negative number (such that it will work for -15, -20, -27 as well as -7) then you have to adjust it after the modulus, like this:
int m = x % 8;
m = (m < 0) ? m + 8 : m;
Essentially this leaves the positive case alone, and will adjust the negative case so the numbers roll over as you want them to.
An alternative way to do this with straight math is to take the modulus twice:
int m = ((x % 8) + 8) % 8
The first modulus gives you your expected range from -7 to 7. The addition adjusts the negative modulus so that it is positive, but of course moves the positive values above 7. The second modulus ensures that all the answers are in the range 0 to 7. This should work for any negative number as well as any positive number.
It sounds like you need to use the % modulo operator. Perhaps write a set of integer functions which work with modulo math, eg. Modulo plus would be =(a+b) % 8;
The modulo operation is what you want. However, the % operator in Java, which is often called modulo, isn't the mathematical modulo. It's rather the remainder operator. The difference is subtle and often irrelevant. It's only important if you have negative parameters like in your case. I think Wikipedia can explain the exact difference.
For you're "wrap around" you need the mathematical version of modulo which sadly isn't implemented in Java for Integer. However, the BigInteger class has a mod() function which does exactly what you need:
BigInteger.valueOf(0-7).mod(BigInteger.valueOf(8)).longValue()
It's not pretty but works.
Um... there is the built-in modulus operator %, which is also present in basically every other language that's at all popular these days.