What does the 31 represent in this method? - java

I have this function to find log of base 2 but I dont understand the meaning of the 31.
public static void loggg(int n){
int result = 0;
for(int i = 0; (n << i & 1 << 31) == 0; i++){
result = (31-i-1);
System.out.println( "result " +result);
}
}
this is my output. it seems like its a max number.
result 30
result 29
result 28
result 27
result 26
result 25
result 24
result 23
result 22
result 21
result 20
result 19
result 18
result 17
result 16
result 15
result 14
result 13
result 12
result 11
result 10
result 9
result 8
result 7
result 6
result 5
result 4

(n << i & 1 << 31) == 0
is an obscure way of writing
(n << i) >= 0
1 << 31 is the binary number 10000000 00000000 00000000 00000000. It's 1, shifted left 31 times.
X & 1 << 31 is a mask, checking if bit 31 is set to 1 in X.
Bit 31 in a signed 32-bit integer is the sign bit. So X & 1 << 31 == 0 is just checking if X is non-negative.

You said this finds the log to the base 2. But since you are working with integers it really only finds the log of the highest power of 2 <= n
An easier way (but not as interesting) is to simply do the following.
System.out.println(31-Integer.numberOfLeadingZeros(n));

Related

Scanner and while loop addition

I just posted yesterday but I am back with another question, I know the answer to this problem but I'm stuck on how they got it.
import java.util.*;
public class test {
public static void main(String[] args) {
String s = "12 13 14 15 18 16 17 20 2";
Scanner c = new Scanner(s);
int sum = 0;
while(c.nextInt()% 2 == 0)
sum += c.nextInt();
System.out.println(sum);
}
}
The output is 44 but I keep getting 46 on my own. I may be doing it wrong since I am not too familiar on how c.nextInt() works.
I am thinking it goes:
12 % 2 = 0, so add 13
14 % 2 = 0, so add 15
18 % 2 = 0, so add 16
17 % 2 =/= 0, so skip
20 % 2 = 0, so add 2
for a total of = 46
am I missing something?
EDIT: Solved, forgot that loops don't just "skip". I'm dumb
Yes , here answer is 44. Here you are repeating while loop until ( number%2 == 0 ) became FALSE.
in your case :
you are adding 13 + 15 + 16 and the next number to check the while condition is 17
here ( 17%2 == 0 ) is FALSE so condition fails and is not entering into the loop .
here comes the total 44 ( 13 + 15 + 16 )
I hope this will help!
Here is a breakdown going through the loop each time:
c.nextInt() gets 12, 12 % 2 == 0, so this condition is TRUE
sum = 0 and c.nextInt() = 13 so sum += 13 equals 13
Second c.nextInt() gets 14, 14 % 2 == 0, so this condition is TRUE
sum = 13 and c.nextInt() = 15 so sum += 15 equals 28
c.nextInt() gets 18, 18 % 2 == 0, so this condition is TRUE
sum = 0 and c.nextInt() = 16, so sum += 16 equals 44
c.nextInt() gets 17, 17 % 2 == 1, so this condition is FALSE, the loop exits
Print 44
Java while loop is used to execute statement(s) until a condition holds true.If the condition holds false , this while loop will be break out.So
17 % 2 != 0, this while loop will be break out.So sum=44.

If statement inside for loops

for (int i = 0; i < 150; i++) {
if (i % 13 == 0) {
System.out.println("#: " + i);
}
}
I just started learning java yesterday and I'm stuck with for loops statement.
I'm confused about part
if (i % 13 == 0)
variable i is initialized to zero int i = 0 and if you divide zero by 13 the result is 0. There's no remainder. I tried on calculator.
But when I run the program. I get the result like this it keeps adding by 13 how?
#: 0
#: 13
#: 26
#: 39
#: 52
#: 65
#: 78
#: 91
#: 104
#: 117
#: 130
#: 143
What you're seeing is correct; it does appear to be adding 13 every time because your if statement is effectively saying, in plain english:
Display the value of i whenever 13 divides i evenly (leaving no remainder)
So indeed, each of the numbers you're seeing divides evenly, leaving no remainder:
#: 0 // 0 / 13 = 0, no remainder
#: 13 // 13 / 13 = 1, no remainder
#: 26 // 26 / 13 = 2, no remainder
and so on...
The results you are seeing are all of the numbers between 0 and 150 (which you specified on this line: for (int i = 0; i < 150; i++) {) that are multiples (have no remainder) of 13
The first loop adds 1 to the int i for each iteration. It will then check if there is a remainder when divided by 13:
(i % 13 == 0)
Finally, it will print that number if it doesn't have a remainder when divided by 13:
System.out.println("#: " + i);
So the result is essentially all the numbers that are multiples of 13 between 0 and 150.

How do I replace a numeric value with a string in Java

I want to print "Two" in the place of 2 and "Four" in the place of 4 in Java within a FOR Loop while printing the numbers from 1 to 50.
For example:
1
Two
3
Four
5
.
.
.
1Four
15
.
.
.
Two1
TwoTwo
Two3
TwoFour
.
.
.
50
Java 8 solution:
public class Play {
public static void main(String[] args) {
rangeClosed(1, 50).forEach(Play::twoOrFour);
}
public static void twoOrFour(long n) {
String result = n + "";
if (n % 10 == 2) {
n /= 10;
result = (n == 0 ? "" : n) + "two"; // the ternary exp: an ugly patch to get rid of the "0" in the first two cases
} else if (n % 10 == 4) {
n /= 10;
result = (n == 0 ? "" : n) + "four";
}
System.out.print(result + " ");
}
}
OUTPUT
1 two 3 four 5 6 7 8 9 10 11 1two 13 1four 15 16 17 18 19 20 21 2two 23 2four 25 26 27 28 29 30 31 3two 33 3four 35 36 37 38 39 40 41 4two 43 4four 45 46 47 48 49 50
UPDATE
In case you want to replace any occurrence of "2" with "two" and "4" with "four" the referenced method can be even simpler:
public static void twoOrFour(long n) {
String result = n + "";
result = result.replaceAll("2", "two").replaceAll("4", "four");
System.out.print(result + " ");
}
which will output:
1 two 3 four 5 6 7 8 9 10 11 1two 13 1four 15 16 17 18 19 two0 two1 twotwo two3 twofour two5 two6 two7 two8 two9 30 31 3two 33 3four 35 36 37 38 39 four0 four1 fourtwo four3 fourfour four5 four6 four7 four8 four9 50
Or if to be even funkier - it can be done in a one-liner:
rangeClosed(1, 50).forEach((x)-> System.out.print((x + " ").replaceAll("2", "two").replaceAll("4", "four")));

How to format an array of integers in java

Currently I have the following method:
public static void printDoubleIntArray(int[][] doubleIntArray) {
for (int x = 0; x < doubleIntArray.length; x++) {
System.out.println();
for (int y = 0; y < doubleIntArray[x].length; y++) {
System.out.print(doubleIntArray[x][y]);
}
}
}
It works perfectly when the parameter "doubleIntArray" is only numbers from 0 - 9 like in the following print out:
0000000
0000300
0033332
0023323
0022223
0023233
0003332
However, if the integers in each element of the array become larger than 9 then I get something like the following:
0000000
000121797
001717171716
0101617171617
001616161617
081617161717
001417171716
What I would like to know is how do I make the above example print out like so:
0 0 0 0 0 0 0
0 0 0 12 17 9 7
0 0 17 17 17 17 16
0 10 16 17 17 16 17
0 0 16 16 16 16 17
0 8 16 17 16 17 17
0 0 14 17 17 17 16
You could try using java.text.NumberFormat and a pattern that displays every number with a fixed width.. Then concatenate them all in a single line...
System.out.print(doubleIntArray[x][y] + "\t");
\t prints a tab
but in this case it will print something like this: (but i guess thats okay for you)
0 0 0 0 0 0 0
0 0 0 12 17 9 7
0 0 17 17 17 17 16
0 10 16 17 17 16 17
0 0 16 16 16 16 17
0 8 16 17 16 17 17
0 0 14 17 17 17 16
Or use String.format("%4d", myinteger) to have each integer occupy 4 chars, and be properly right padded.
System.out.printf("%4d", doubleIntArray[x][y]);
4 represents the minimum space that the number will print.
The other options for this method are explained here
You have 2 options. Firstly, you can use \t in the second for loop. But I think you could add \t and whitespace character to avoid deterioration. Can provide this too, adding if-else structure in second for loop. I mean
if(doubleIntArray[y].length<10){
System.out.print(doubleIntArray[x][y] + "\t ");
//Tab+two whitespace.
} else {
if(doubleIntArray[y].length>10) {
System.out.print(doubleIntArray[x][y] + "\t ");
//Tab+one whitespace
} else {
System.out.print(doubleIntArray[x][y] + "\t");
//Tab+NO whitespace
}
}
Logic is that I think. Sorry for my answers design. I am on the bus now and I cannot write smoothly. If I had a mistake sorry about that again.
public static void printDoubleIntArray(int[][] doubleIntArray) {
for (int x = 0; x < doubleIntArray.length; x++) {
System.out.println();
for (int y = 0; y < doubleIntArray[x].length; y++) {
System.out.print(doubleIntArray[x][y],"\t");
}
System.out.print("\n");
}
}

Shift operator in Java bizarre program output

I came across the following program and it behaving in unexpected manner.
public class ShiftProgram
{
public static void main(String[] args)
{
int i = 0;
while(-1 << i != 0)
i++;
System.out.println(i);
}
}
If we think about this program output, when it reaches 32 while loop condition should return false and terminate and it should print 32.
If you ran this program, it does not print anything but goes into an infinite loop. Any idea whats going on? Thank you in advance.
Have you tried printing out (-1 << i) in the loop to see what's going wrong? If you do, you'll see that it goes:
-1 << 0 = -1
-1 << 1 = -2
-1 << 2 = -4
-1 << 3 = -8
-1 << 4 = -16
-1 << 5 = -32
-1 << 6 = -64
-1 << 7 = -128
-1 << 8 = -256
-1 << 9 = -512
-1 << 10 = -1024
-1 << 11 = -2048
-1 << 12 = -4096
-1 << 13 = -8192
-1 << 14 = -16384
-1 << 15 = -32768
-1 << 16 = -65536
-1 << 17 = -131072
-1 << 18 = -262144
-1 << 19 = -524288
-1 << 20 = -1048576
-1 << 21 = -2097152
-1 << 22 = -4194304
-1 << 23 = -8388608
-1 << 24 = -16777216
-1 << 25 = -33554432
-1 << 26 = -67108864
-1 << 27 = -134217728
-1 << 28 = -268435456
-1 << 29 = -536870912
-1 << 30 = -1073741824
-1 << 31 = -2147483648
-1 << 32 = -1
-1 << 33 = -2
-1 << 34 = -4
-1 << 35 = -8
-1 << 36 = -16
[.. etc ..]
According to the language specification:
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.
... so the result will always remain negative.
That document also tells you that:
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (ยง15.22.1) with the mask value 0x1f. The shift distance actually used is therefore always in the range 0 to 31, inclusive.
So if you use a shift of 32, that's interpreted as a shift of 32 & 0x1f, which is 0. -1 shifted by 0 is still just -1, not 0.
The shift count is interpreted modulo the number of bits in an int (32), and so i << 32 is just i << 0 which is i. Thus, you will never get 0 as the result. My source for that is http://www.janeg.ca/scjp/oper/shift.html. If you do something like int n = -1; while (n != 0) {i++; n <<= 1;}, it will eventually reach 0 like you want.

Categories