Referring to page number 79 of " Java The complete Reference" 7th edition by Herbert Schildt.
The author says : " If the integer’s value is larger than the range of a
byte, it will be reduced modulo (the remainder of an integer division by the) byte’s range".
The range of byte in java is -128 to 127. So the maximum value that fits in a byte is 128. If an integer value is assigned to a byte as shown below :
int i = 257;
byte b;
b = (byte) i;
Since 257 crosses the range 127, 257 % 127 = 3 should be stored in 'b'.
But am getting the output as 1 instead of 3.
Where have I gone wrong in understanding the concept?
Just consider the binary representation of the numbers :
257 is represented in binary as 00000000 00000000 00000001 00000001
When you cast this 32 bits int to an 8 bits byte, you keep only the lowest 8 bits :
00000001
which is 1
257 = 00000000 000000000 00000001 00000001 in bits and a byte is made up of 8 bits only...
As a result only the lower 8 bits are stored and 1 is the output.
Related
public void int2byte(){
int x = 128;
byte y = (byte) x;
System.out.println(Integer.toHexString(y));
}
I got result ffffff80, why not 80?
I got result 7f when x = 127.
Bytes are signed in Java. When you cast 128 to a byte, it becomes -128.
The int 128: 00000000 00000000 00000000 10000000
The byte -128: 10000000
Then, when you widen it back to an int with Integer.toHexString, because it's now negative, it gets sign-extended. This means that a bunch of 1 bits show up, explaining your extra f characters in the hex output.
You can convert it in an unsigned fashion using Byte.toUnsignedInt to prevent the sign extension.
Converts the argument to an int by an unsigned conversion. In an unsigned conversion to an int, the high-order 24 bits of the int are zero and the low-order 8 bits are equal to the bits of the byte argument.
System.out.println(Integer.toHexString(Byte.toUnsignedInt(y)));
An alternative is to bit-mask out the sign-extended bits by manually keeping only the 8 bits of the byte:
System.out.println(Integer.toHexString(y & 0xFF));
Either way, the output is:
80
This is because a positive value of 128 cannot be represented with a signed byte
The range is -128 to 127
So your int becomes sign-extended so instead of 0x00000080 you get 0xffffff80
Edit: As others have explained:
Integer 128 shares the last 8 bits with the byte (-128)
The difference is that Integer 128 has leading zeros.
0x00000080 (0000 0000 0000 0000 0000 0000 1000 0000)
while the byte -128 is just
0x80 (1000 0000)
When you convert byte -128 using Integer.toHexString() it takes the leading 1 and sign-extends it so you get
0xffffff80 (1111 1111 1111 1111 1111 1111 1000 0000)
What I want to do is storing a 64-bit unsigned integer as a Long type, preserving its interval binary representation.
For example, I want to save
2^63-1 = 9223372036854775807 as it is (9223372036854775807) (∵ 2^63-1 <= Long.MAX_VALUE)
and
2^63 = 9223372036854775808 = 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000(2) as -9223372036854775808
because 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000(2) is -9223372036854775808's binary representation for the signed 64-bit integer type.
Likewise, I want to save 2^64-1 = 18446744073709551615 as -1
because (unsigned) 18446744073709551615 = 0xFFFFFFFFFFFFFFFF and (signed long) -1 = 0xFFFFFFFFFFFFFFFF
JavaDoc for BigInteger.longValue() says that
Converts this BigInteger to a long. This conversion is analogous to a
narrowing primitive conversion from long to int as defined in section
5.1.3 of The Java™ Language Specification: if this BigInteger is too big to fit in a long, only the low-order 64 bits are returned. Note
that this conversion can lose information about the overall magnitude
of the BigInteger value as well as return a result with the opposite
sign.
However, I am not sure it is guaranteed to work as I intended.
Will BigInteger(string).longValue() be enough for my purpose where string is the string representation of the original integer?
Update: I am using JDK 1.7, so Long.parseUnsignedLong() is not available.
In this case, I would just run the code and see what happens.
println(new BigInteger("2").pow(63).longValue());
println(new BigInteger("2").pow(63).subtract(new BigInteger("1")).longValue());
println(new BigInteger("2").pow(64).longValue());
println(new BigInteger("2").pow(64).subtract(new BigInteger("1")).longValue());
Outputs
-9223372036854775808
9223372036854775807
0
-1
So yes, BigInteger.longValue() does exactly what you think it does (and according to the reading of the docs, this is the guaranteed behavior. AKA, it is converted to a bit array, and only the low 64 bits are kept and used as long value, ignoring the fact that the 64'th bit is actually the sign bit).
You should use unsigned long methods in Long class.
String s = "18446744073709551615"; // 2^64 - 1
long value = Long.parseUnsignedLong(s);
System.out.println("long value = " + value);
System.out.println("unsigned long value = " + Long.toUnsignedString(value));
result
long value = -1
unsigned long value = 18446744073709551615
int a=128;
byte b;
b=(byte)a;
System.out.println(b);
This prints -128.
But in the Java book the same code outputs 0.
What's the difference between them?
128 represented as a 32-bit integer (int) is 00000000 00000000 00000000 10000000 in binary.
As a byte is only 8 bits, when it is cast to a byte it becomes 10000000. Because all integers in Java are signed integers using two's complement, the first bit (1) is the sign bit, therefore the value becomes -128.
Not sure why the book said the output should be 0. Are you sure the example is exactly the same in the book?
More information on the Java primitives types here and Wikipedia has a fairly comprehensive article on two's complement.
Look, 128 = 0x80, so if you cut off all but less significant byte you will get 1000 0000 (binary). This is -128 for byte.
So there is an error in you java book:)
In Java this should really print -128. If a = 256 it should print 0.
Byte is from -128 to 127, so if you cast 127 it is 127 and 128 is -128 because 127 + 1 = -128.
Right answer was posted already but id like to expand it a little.
To understand better how it works, try to read about it form other sources. #DanielGibbs provided few you could use
i suggest you also try to run code like:
for (int a = -256; a < 256; a++) {
byte b = (byte) a;
System.out.println(a + " -> " + b);
}
output of this code should let you see clearly meaning of less significant (and one most significant which determines sign) bites in int and how they are fit in byte type.
PS. -256 is not 10000000 00000000 00000001 00000000, but 11111111 11111111 11111111 00000000.
I'm trying to solve this problem: I have a byte value (1 byte) and I need to transform this value into a long value (8 bytes). But what I want is just replace the first byte of the long variable with the byte value I had before.
A example:
My Byte Value: 11001101
My Long Value: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
What I want: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11001101
Simple as that!
I'm trying to do this (example):
byte b = -112;
long l = 0;
l = l | b;
System.out.println(l);
But I get the result -112! In my understanding, the java bit or operator should do an "or" with the first byte of the long value and the byte value. Instead, the or operator is copying the 2-complement representation of the byte value into the long value, and this is not what I want.
The result I was expecting in that case was 144, since -112 is 10010000, which is 144 when considering a unsigned value.
Hope you understand me. Thanks!
What happens here is that b is cast to long, and this is done via sign extension: the most-significant bit (1) is repeated, hence 7 11111111 bytes are used as padding. The remedy here is to explicitly consider only the 8 least-significant bits in the resulting value, using a bitwise and (&):
l = l | ((long)b & 0xff);
Java promotes the signed byte to a signed long before doing math operations, and that sign extends the byte.
To fix it, you can do this:
l = l | (0xFF & (long)b))
or
l |= 0xFF & (long)b
(This works because 0xFF is a positive int value. If it was a byte, it'd also get sign extended to a negative long.) (Casting b to an int here would work as well as casting to a long.)
I was wondering the meaning of "Bitwise Shifting". Currently I am trying to create Image Filters in Java using BufferedImage. I found some good answers on how to access the RGB values individually in other posts but wasnt exactly sure on how it works. I understand the RGB values are stored in a 32-bit int each 8-bit part representing the value.
This is what I was looking at: a link
Basically looking for someone to explain this process, the Google searches Ive done were too technical.
When you have a single integer that contains multiple bytes of information, then masking and shifting are the processes used to access the individual pieces. Assuming the bytes are stored like such (they probably aren't, but...) then this is what you could do to retrieve them:
aRGB: 255, 65, 33, 17
binary: 11111111 01000001 00100001 00010001
To retrieve the red value (65) from a variable x:
x && 0x00FF0000
11111111 01000001 00100001 00010001
* 00000000 11111111 00000000 00000000
-------------------------------------
00000000 01000001 00000000 00000000
Then the shifting operation, to move the bits to where they make sense as a lone value:
00000000 01000001 00000000 00000000 >> 16 = 00000000 00000000 00000000 01000001
The binary mask captures only the second byte of the value, by setting all the other bits to 0; only the bits that match the second byte remain as they are (multiplied by 1, not 0). Then, you shift the bits to the right 16 places, to strip off those extra 0's. Obviously, the leading 0's no longer matter, so the result is just a plain binary 01000001, or decimal 65.
It is technical in nature. You store a value 0 - 255, or in binary:
from
00000000
to
11111111
then you take a larger container like this one:
0000000000000000
and insert it there so if your color is 117
0000000001110101
and shift it to the left one byte so you get
0111010100000000
then you add the second color, say it 65 or 01000001 and get
0111010101000001
then you again shift it one byte to the left and get
011101010100000100000000
at last you add the third color and its for example a 255 or 11111111 you get
011101010100000111111111
so you have stored three values 0 - 255 via bitshift.
There is more than one way to think about a pattern of bits in memory. Usually, we think of the bits stored in an integer as representing a single number. The higher-order bits contribute greater value than the lower-order bits and their values are summed to arrive at a single number, so the following pattern:
00001101 00110000 00000111
Would be interpreted as:
2^0 + 2^1 + 2^3 + 2^13 + 2^14 + 2^15 + 2^17 + 2^18 = 864,263
But we're free to think of this pattern as three individual groups of 8-bit numbers (each representing the numeric value of a color component). However, to convert a bit pattern in the higher-order bits into the number we intend it to represent, we need to interpret those bits as though they appeared in the rightmost 8-bit group. This is why we shift.
For example, to get the value of the leftmost 8-bit group, we need to mask all bits not in that group, and then shift those bits 16 places to the right, so that they occupy the rightmost position:
// first, assume n = 00001101 00110000 00000111
(n & 0xFF0000) >> 16 // red
Zeros are automatically shifted into the vacated bits, leaving:
00000000 00000000 00001101
Which we can now interpret as:
13
Similarly, we can calculate the value of the bits in the center and rightmost groups:
(n & 0x00FF00) >> 8 // green
n & 0x0000FF // blue (no shift necessary)
Setting the value of one of these components requires shifting in the other direction. For example, the following shifts 75 into the center 8-bit position:
n = (n & (0xFF00FF)) | (75 << 8)
We're first resetting the green value (with the 0xFF00FF mask) and then shifting the number 75 8 bits to the left. Finally, we combine these two numbers.
We can see that this works by shifting it back out again:
(n & 0x00FF00) >> 8 // => 75
Resetting or maximizing one of the components is even simpler. As we've seen in the earlier example, zero-ing a component can be done like this:
n = n & 0xFF00FF // clear out green
The following mask, on the other hand, maximizes the value of the green component:
n = n | 0x00FF00
Bitwise operations are operations on the bits of the binary representation of the data rather than the data represented as an integer or floating point number. For example, 8 may be represented as 1000 in binary. Shifting it to the right twice moves all the digits to the right by 3, padding with 0's, resulting in 0010, or 2.
For more, see the Wikipedia article.