I have tried to convert 248 to binary and then convert it to two's compliment and finally convert it back to decimal.
Problem: result is 8 not -8
Convert the hex number digit by digit to a 4-bit binary, for example (A) to (1010) and put then together. Now you can calculate the 2‘s complement as explained below.
You'll see you need at least 9 bits for (F8)16, so if you're only working with a 8-bit variable for instance, you might encounter issues.
Calculating the 2‘s complement:
(248)10 = (0 1111 1000)2.
Complement all the bits:
(1 0000 0111)2.
Add 1:
(1 0000 1000)2.
This will give you (-248)10. Notice that if you're only looking at the last 8 bits (0000 1000)2, the bit string evaluates to 8. I hope this helps in some way.
Java specifically keeps a single byte in the min/max range of -128 to 127.
A value like 248 (hex: 0xF8) is already stored as a Short (2 bytes or 16 bits) in Java.
[0000 0000] [1111 1000] = 248 in Java. But you need only [1111 1000] for -8.
You'd think "If I remove starting byte [0000 0000] then it works..??" No because now you have 1 byte left and that remaining byte with [1111 1000] alone cannot make 248 since Java's maximum for a single byte is 127.
Solution:
In those available 16 bits, replace all bits leading up to your value with 1.
Visually your bits [0000 0000] [1111 1000] = 248 must become as [1111 1111] [1111 1000] = -8.
One quick way to achieve the result is through this logic result = (-256) | ( x );.
Code example:
int x = 248; //# your input value from reading
int result = (-256) | ( x );
System.out.println("value is " + result ); //# gives: value is -8
What function does the ^ (caret) operator serve in Java?
When I try this:
int a = 5^n;
...it gives me:
for n = 5, returns 0
for n = 4, returns 1
for n = 6, returns 3
...so I guess it doesn't perform exponentiation. But what is it then?
The ^ operator in Java
^ in Java is the exclusive-or ("xor") operator.
Let's take 5^6 as example:
(decimal) (binary)
5 = 101
6 = 110
------------------ xor
3 = 011
This the truth table for bitwise (JLS 15.22.1) and logical (JLS 15.22.2) xor:
^ | 0 1 ^ | F T
--+----- --+-----
0 | 0 1 F | F T
1 | 1 0 T | T F
More simply, you can also think of xor as "this or that, but not both!".
See also
Wikipedia: exclusive-or
Exponentiation in Java
As for integer exponentiation, unfortunately Java does not have such an operator. You can use double Math.pow(double, double) (casting the result to int if necessary).
You can also use the traditional bit-shifting trick to compute some powers of two. That is, (1L << k) is two to the k-th power for k=0..63.
See also
Wikipedia: Arithmetic shift
Merge note: this answer was merged from another question where the intention was to use exponentiation to convert a string "8675309" to int without using Integer.parseInt as a programming exercise (^ denotes exponentiation from now on). The OP's intention was to compute 8*10^6 + 6*10^5 + 7*10^4 + 5*10^3 + 3*10^2 + 0*10^1 + 9*10^0 = 8675309; the next part of this answer addresses that exponentiation is not necessary for this task.
Horner's scheme
Addressing your specific need, you actually don't need to compute various powers of 10. You can use what is called the Horner's scheme, which is not only simple but also efficient.
Since you're doing this as a personal exercise, I won't give the Java code, but here's the main idea:
8675309 = 8*10^6 + 6*10^5 + 7*10^4 + 5*10^3 + 3*10^2 + 0*10^1 + 9*10^0
= (((((8*10 + 6)*10 + 7)*10 + 5)*10 + 3)*10 + 0)*10 + 9
It may look complicated at first, but it really isn't. You basically read the digits left to right, and you multiply your result so far by 10 before adding the next digit.
In table form:
step result digit result*10+digit
1 init=0 8 8
2 8 6 86
3 86 7 867
4 867 5 8675
5 8675 3 86753
6 86753 0 867530
7 867530 9 8675309=final
As many people have already pointed out, it's the XOR operator. Many people have also already pointed out that if you want exponentiation then you need to use Math.pow.
But I think it's also useful to note that ^ is just one of a family of operators that are collectively known as bitwise operators:
Operator Name Example Result Description
a & b and 3 & 5 1 1 if both bits are 1.
a | b or 3 | 5 7 1 if either bit is 1.
a ^ b xor 3 ^ 5 6 1 if both bits are different.
~a not ~3 -4 Inverts the bits.
n << p left shift 3 << 2 12 Shifts the bits of n left p positions. Zero bits are shifted into the low-order positions.
n >> p right shift 5 >> 2 1 Shifts the bits of n right p positions. If n is a 2's complement signed number, the sign bit is shifted into the high-order positions.
n >>> p right shift -4 >>> 28 15 Shifts the bits of n right p positions. Zeros are shifted into the high-order positions.
From here.
These operators can come in handy when you need to read and write to integers where the individual bits should be interpreted as flags, or when a specific range of bits in an integer have a special meaning and you want to extract only those. You can do a lot of every day programming without ever needing to use these operators, but if you ever have to work with data at the bit level, a good knowledge of these operators is invaluable.
It's bitwise XOR, Java does not have an exponentiation operator, you would have to use Math.pow() instead.
XOR operator rule =>
0 ^ 0 = 0
1 ^ 1 = 0
0 ^ 1 = 1
1 ^ 0 = 1
Binary representation of 4, 5 and 6 :
4 = 1 0 0
5 = 1 0 1
6 = 1 1 0
now, perform XOR operation on 5 and 4:
5 ^ 4 => 1 0 1 (5)
1 0 0 (4)
----------
0 0 1 => 1
Similarly,
5 ^ 5 => 1 0 1 (5)
1 0 1 (5)
------------
0 0 0 => (0)
5 ^ 6 => 1 0 1 (5)
1 1 0 (6)
-----------
0 1 1 => 3
It is the XOR bitwise operator.
Lot many people have already explained about what it is and how it can be used but apart from the obvious you can use this operator to do a lot of programming tricks like
XORing of all the elements in a boolean array would tell you if the array has odd number of true elements
If you have an array with all numbers repeating even number of times except one which repeats odd number of times you can find that by XORing all elements.
Swapping values without using temporary variable
Finding missing number in the range 1 to n
Basic validation of data sent over the network.
Lot many such tricks can be done using bit wise operators, interesting topic to explore.
XOR operator rule
0 ^ 0 = 0
1 ^ 1 = 0
0 ^ 1 = 1
1 ^ 0 = 1
Bitwise operator works on bits and performs bit-by-bit operation. Assume if a = 60 and b = 13; now in binary format they will be as follows −
a = 0011 1100
b = 0000 1101
a^b ==> 0011 1100 (a)
0000 1101 (b)
------------- XOR
0011 0001 => 49
(a ^ b) will give 49 which is 0011 0001
As others have said, it's bitwise XOR. If you want to raise a number to a given power, use Math.pow(a , b), where a is a number and b is the power.
AraK's link points to the definition of exclusive-or, which explains how this function works for two boolean values.
The missing piece of information is how this applies to two integers (or integer-type values). Bitwise exclusive-or is applied to pairs of corresponding binary digits in two numbers, and the results are re-assembled into an integer result.
To use your example:
The binary representation of 5 is 0101.
The binary representation of 4 is 0100.
A simple way to define bitwise XOR is to say the result has a 1 in every place where the two input numbers differ.
With 4 and 5, the only difference is in the last place; so
0101 ^ 0100 = 0001 (5 ^ 4 = 1) .
It is the Bitwise xor operator in java which results 1 for different value of bit (ie 1 ^ 0 = 1) and 0 for same value of bit (ie 0 ^ 0 = 0) when a number is written in binary form.
ex :-
To use your example:
The binary representation of 5 is 0101.
The binary representation of 4 is 0100.
A simple way to define Bitwise XOR is to say the result has a 1 in every place where the two input numbers differ.
0101 ^ 0100 = 0001 (5 ^ 4 = 1) .
To perform exponentiation, you can use Math.pow instead:
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Math.html#pow%28double,%20double%29
As already stated by the other answer(s), it's the "exclusive or" (XOR) operator. For more information on bit-operators in Java, see: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html
That is because you are using the xor operator.
In java, or just about any other language, ^ is bitwise xor,
so of course,
10 ^ 1 = 11.
more info about bitwise operators
It's interesting how Java and C# don't have a power operator.
It is the bitwise xor operator in java which results 1 for different value (ie 1 ^ 0 = 1) and 0 for same value (ie 0 ^ 0 = 0).
^ is binary (as in base-2) xor, not exponentiation (which is not available as a Java operator). For exponentiation, see java.lang.Math.pow().
It is XOR operator. It is use to do bit operations on numbers. It has the behavior such that when you do a xor operation on same bits say 0 XOR 0 / 1 XOR 1 the result is 0. But if any of the bits is different then result is 1.
So when you did 5^3 then you can look at these numbers 5, 6 in their binary forms and thus the expression becomes (101) XOR (110) which gives the result (011) whose decimal representation is 3.
As an addition to the other answers, it's worth mentioning that the caret operator can also be used with boolean operands, and it returns true (if and only if) the operands are different:
System.out.println(true ^ true); // false
System.out.println(true ^ false); // true
System.out.println(false ^ false); // false
System.out.println(false ^ true); // true
^ = (bitwise XOR)
Description
Binary XOR Operator copies the bit if it is set in one operand but not both.
example
(A ^ B) will give 49 which is 0011 0001
In other languages like Python you can do 10**2=100, try it.
I am trying to perform a bitwise not on a 128 bit BigInteger in Java. I have a 128 bit number which has the first 64 bits set to 1 and the last 64 bits set to 0 (I am playing with IPv6 masks).
BigInteger b = new BigInteger(2).pow(64).subtract(BigInteger.ONE).shiftLeft(64);
System.out.println(b.toString(2));
This results in the following, if I output it using base 2:
11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000
I am trying to flip/reverse all the bits using a bitwise not.
System.out.println(b.not().toString(2));
From my understanding of a bitwise not, I was expecting all the 1's to change to 0's and all the 0's to change to 1's, but I get the following instead:
-11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000
This also seems to match the documentation of the not() function:
This method returns a negative value if and only if this BigInteger is non-negative
Is it a case of looping through all 128 bits and performing a bitwise not on each separate bit instead?
UPDATE
It probably helps if I try and explain what I was trying to achieve to give some context. I am manipulating IPv6 addresses and was trying to determine if a given IPv6 address was within a subnet or not based on an IPv6 mask.
Based on the responses, I think the following should work:
E.g.
Is 2001:db8:0:0:8:800:200c:417b within 2001:db8::/64?
BigInteger n = new BigInteger(1, InetAddress.getByName("2001:db8::").getAddress());
BigInteger b = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE).shiftLeft(64);
// First Address in Subnet
BigInteger first = n.and(b);
// Last Address in Subnet (this is where I was having a problem as it was returning a negative number)
BigInteger MASK_128 = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
BigInteger last = first.add(b.xor(MASK_128));
// Convert our test IP into BigInteger
BigInteger ip = new BigInteger(1, InetAddress.getByName("2001:db8:0:0:8:800:200c:417b").getAddress());
// Check if IP is >= first and <= last
if ((first.compareTo(ip) <= 0) && (last.compareTo(ip) >= 0)) {
// in subnet
}
As others have pointed out, it's the sign bit that is giving you the result that you don't want.
There are a couple of ways that you can get the inverted bits. For both of them you will need a 128 bit mask value:
private static final BigInteger MASK_128 =
BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
Then you can either mask the sign bit:
BigInteger b = BigInteger.valueOf(2).pow(64).subtract(BigInteger.ONE).shiftLeft(64);
System.out.println(MASK_128.andNot(b).toString(2));
Or invert directly using xor:
System.out.println(b.xor(MASK_128).toString(2));
I expect the mask value will be useful elsewhere once you start fleshing things out also.
signed byte 64 = 01000000
Invert it
and we get signed byte -65 = 10111111
Sign "minus" is the "not" operator itself:
-1000000 = 0111111
Type this and you see that the values are equal (+1) in absolute
System.out.println(b.toString());
System.out.println(b.not().toString());
Your answer is perfectly correct ,In java everything is in two's compliment:
Convert Decimal to Two's Complement
Convert the number to binary (ignore the sign for now) e.g. 5 is 0101 and -5 is 0101
If the number is a positive number then you are done. e.g. 5 is 0101 in binary using twos complement notation.
Here goes your solution.
If the number is negative then
3.1 find the complement (invert 0's and 1's) e.g. -5 is 0101 so finding the complement is 1010
3.2 Add 1 to the complement 1010 + 1 = 1011. Therefore, -5 in two's complement is 1011.
So, what if you wanted to do 2 + (-3) in binary? 2 + (-3) is -1. What would you have to do if you were using sign magnitude to add these numbers? 0010 + 1101 = ?
Using two's complement consider how easy it would be.
2 = 0010
-3 = 1101
+
-1 = 1111
Converting Two's Complement to Decimal
Converting 1111 to decimal:
The number starts with 1, so it's negative, so we find the complement of 1111, which is 0000.
Add 1 to 0000, and we obtain 0001.
Convert 0001 to decimal, which is 1.
Apply the sign = -1.
In your case
when you do b.not().toString(2) , you will get the response :
-11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000001
with 1 at the last bit.
Now do the two's compliment and you will get the right answer.
e.g; Flip all the 1's by 0's and vice-versa. after doing that add one to the solution and you will get the solution that you are seeking.
Final solution
00000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111
Use
VALUE = 0xFFFFFFFFFFFFFFFF0000000000000000 - this is patern for bit 1...10...0
VALUE = 0x0000000000000000FFFFFFFFFFFFFFFF - this is patern for bit 0...01...1
Just type by hand 16 x "F" and "0" and remember to add "0x"before each pattern.
Define this values as final.
If You want to generate such values you must do
value += 0x1;
value << 1;
For n times. In your case n is 64.
I think understand what they fundamentally do - operate on bits (flip, shift, invert, etc...).
My issue is that I don't know when I'd ever need to use them, and I don't think I fully understand bits.
I know that there are 8 bits in a byte and I know that bits are either a 0 or 1. Now here is where I start to get confused... I believe data types define combinations of bits differently. So if I declare an int, 32 bits are set aside for numbers, if I declare a char, 8 bits are set aside and the bits for that data type define a letter.
Running with that idea, I did the following basic operation in java which confuses me:
int num = 00000010;
System.out.println(num);
This prints 8 and if I define num this way:
int num = 00000100;
System.out.println(num);
This prints 64
So to practice with bitwise operations (just for the hell of it) I tried this:
int num = 00000010 << 1;
System.out.println(num);
And it prints 16 where as I thought it would shift the bits by one to the left and print 64.
What is happening here, and when would I ever need to apply this method of manipulating bits?
You are accidentally specifying an octal literal when you specify a number with a leading zero.
00000010 => 1*8^1 + 0*8^0 => 8
00000100 => 1*8^2 + 0*8^1 + 0*8^0 => 64
The JLS, Section 3.10.1, describes octal and binary literals:
An octal numeral consists of an ASCII digit 0 followed by one or more
of the ASCII digits 0 through 7 interspersed with underscores, and can
represent a positive, zero, or negative integer.
A binary numeral consists of the leading ASCII characters 0b or 0B
followed by one or more of the ASCII digits 0 or 1 interspersed with
underscores, and can represent a positive, zero, or negative integer.
You are bit-shifting your 8 by one to the left, effectively multiplying it by 2 to get 16. In bits:
00000100 => 00001000
(8 => 16)
Binary literals are expressed with leading 0b, e.g.:
0b000010 => 2
My simple question is why:
System.out.println(010|4);
prints "12"? I understand bitwise OR operator but why "010" equals 8? It's definitely not compliment 2's notification, so how to decode this number?
A leading 0 denotes an octal numeric value so the value 010 can be decoded thus: 010 = 1 * 81 + 0 * 80 = 8
Have a look at the Java Language Specification, Chapter 3.10.1 Integer Literals
An integer literal may be expressed in decimal (base 10), hexadecimal
(base 16), octal (base 8), or binary (base 2).
[...]
An octal numeral consists of an ASCII digit 0 followed by one or more
of the ASCII digits 0 through 7 interspersed with underscores, and can
represent a positive, zero, or negative integer.
Now you should understand why 010 is 8.
That is because java takes it as an octal literal and hence produces 12. Try System.out.println(10|4) and the result is 14. Because this time it is taken as decimal literal.
As everybody mentioned here that 010 is an Octal Integer literal . The leading 0 specifies that it is an octal representation . Actual value will be :
1*8^1 + 0*8^0 = 8(decimal) = 1000(binary-only last 4 digits)
Now coming back to the SOP :
System.out.println(010|4);
Applying Bitwise OR on 010 and 4(considering only the last 4 digits) =>
1000|0100
= 1100
= 1*2^3 + 1*2^2 + 0*2^1 + 0*2^0
= 8 + 4 + 0 + 0
= 12(decimal)
Any number in Java which fulfill the below Conditions -
A. number Should have three or More Digital
B.Number should Start with 0.
If above Condition are true then number treated as Octal_Base (8) Number.
Therefore,
010=(8^2)*0+(8^1)*1+(8^0)*0=64*0+8*1+1*0=8
So,
010=8
One point you should consider that the number will be in octal if "0XX" i.e. both X are in range [0,7], otherwise it will result in "Integer number too large".