I have written the following code but findbugs is shwowing this error: BIT_ADD_OF_SIGNED_BYTE. I tried a lot but may be I am not getting the concept of left shift correctly.
void problem() {
byte [] byteArray = {1, 2, 3, 4, 5};
int localOne = 0;
for(int i = 0; i < 4; i++) {
localOne = (localOne<<8) + byteArray[i];
}
}
You'r doing the shift correctly, your (possible) error is when adding a signed byte to an int
Because of sign extension you need to do this:
localOne = (localOne<<8) + (0xFF & byteArray[i]);
Say you have the byte 80 (hex), which is 1000 0000 (binary), this is -128 (decimal) because of the two's complement representation. Now, when adding it to an int it first gets converted to an int. The resulting int is not
0000 0000 0000 0000 0000 0000 1000 0000
(binary) it will be
1111 1111 1111 1111 1111 1111 1000 0000
(binary) because of sign extension. To get the first, you have to apply a bitwise and with 0xFF wich is this in binary:
0000 0000 0000 0000 0000 0000 1111 1111
Related
Recently I was given a codility problem which says the following code has a bug.
So, the code problem is that we have a 30-bit unsigned integer from N[29]... N[0] and performing the right cyclic shift (>>) should give us a number like N[0]N[29]... N[1].
Our goal is to find the number of right shifts which produce the maximum value achievable from a given number.
For Example:
for N = 9736 (00 0000 0000 0000 0010 0110 0000 1000)
9736 >> 1 = 4868 -> 00 0000 0000 0000 0001 0011 0000 0100
.
.
.
9736 >> 11 = 809500676 -> 11 0000 0100 0000 0000 0000 0000 0100
.
.
till 30 (as we have 30 bits integers)
from the example above on the 11th iteration, we receive the maximum number possible for 9736.
Hence the answer = 11
Given Code:
int shift(int N) {
int largest = 0;
int shift = 0;
int temp = N;
for (int i = 1; i < 30; ++i) {
int index = (temp & 1);
temp = ((temp >> 1) | (index << 29));
if (temp > largest) {
largest = temp;
shift = i;
}
}
return shift;
}
N is in range [0... 1,073,741,823]
I tried but couldn't find the bug here or the test case where this fails.
It fails for 0b10000...000 (0x20000000), Because the largest value is for shift==0
the simplest solution is to define largest as N instead of 0.
Please, describe what these n| = n >>> x 5 lines do?
I am not interested in what | or >>> operators do.
I am interested in what that complex logic do under cover in a math language.
/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
All (positive) powers of two have exactly 1 bit set; and (power of 2 - 1) has all of the bits set less than the most significant bit. So, we can find the next largest power of two by
Subtracting 1
Setting all of the less significant bits
Adding 1 back
These bit shifting operations are implementing the second step of this process, by "smearing" the set bits.
So:
n |= n >>> 1;
Would do something like:
01010000
| 00101000
= 01111000
If you do this again, you "smear" the number down again (still shifting by just 1):
01111000
| 00111100
= 01111100
Keep on doing this, and you will end up with a number with all of the less significant bits set:
01111111
In the worst case, you'd have to do this 30 times (for a positive, signed 32 bit integer), when the most significant bit is the 31st bit:
01xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
=> 011xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
=> 0111xxxxxxxxxxxxxxxxxxxxxxxxxxxx
=> 01111xxxxxxxxxxxxxxxxxxxxxxxxxxx
=> 011111xxxxxxxxxxxxxxxxxxxxxxxxxx
...
=> 01111111111111111111111111111111
(x just means it could be a zero or a one)
But you might notice something interesting: after the first smear, when shifting by 1, we have the two most significant bits set. So, instead of shifting by 1, we can skip an operation by shifting by 2:
01xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
=> 011xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
=> 01111xxxxxxxxxxxxxxxxxxxxxxxxxxx
Continuing with this pattern, shift by 4 next:
=> 011111111xxxxxxxxxxxxxxxxxxxxxxx
Shift by 8:
=> 01111111111111111xxxxxxxxxxxxxxx
Shift by 16:
=> 01111111111111111111111111111111
So, instead of taking 30 operations to set all the less significant bits, we have taken 5.
To understand the process lets assume the value of cap passed is 10.
So n = capacity - 1 = 9; 0000 1001
n |= n >>> 1 = 0000 1101
n |= n >>> 2 = 0000 1111
n |= n >>> 4 = 0000 1111
n |= n >>> 8 = 0000 1111
n |= n >>> 16 = 0000 1111 = 15
Finally the method returns n + 1 = 16
For large numbers
cap = 0000 1000 0000 0000 0000 0000 0000 0001
n = cap - 1 = 0000 1000 0000 0000 0000 0000 0000 0000
n |= n >>> 1 = 0000 1100 0000 0000 0000 0000 0000 0000
n |= n >>> 2 = 0000 1111 0000 0000 0000 0000 0000 0000
n |= n >>> 4 = 0000 1111 1111 0000 0000 0000 0000 0000
n |= n >>> 8 = 0000 1111 1111 1111 1111 0000 0000 0000
n |= n >>> 16 = 0000 1111 1111 1111 1111 1111 1111 1111
return n + 1 = 0001 0000 0000 0000 0000 0000 0000 0000
I am porting some C++ samples to Java
I am now stuck trying to pack four integers into a single one in the following layout [10, 10, 10, 2] in bits, that is the first int will occupy the first 10 bits, similar for the second and third one, while the last one just the last two bits.
In the C++ sample, this is the code to pack them:
GLM_FUNC_QUALIFIER uint32 packSnorm3x10_1x2(vec4 const & v)
{
detail::i10i10i10i2 Result;
Result.data.x = int(round(clamp(v.x,-1.0f, 1.0f) * 511.f));
Result.data.y = int(round(clamp(v.y,-1.0f, 1.0f) * 511.f));
Result.data.z = int(round(clamp(v.z,-1.0f, 1.0f) * 511.f));
Result.data.w = int(round(clamp(v.w,-1.0f, 1.0f) * 1.f));
return Result.pack;
}
Result.data is the following struct:
union i10i10i10i2
{
struct
{
int x : 10;
int y : 10;
int z : 10;
int w : 2;
} data;
uint32 pack;
};
With an input equal to [-1f,-1f,0f,1f] we get a Result.data equal to [-511,-511,0,1] and this return value 1074267649, that, in binary is:
0 -511
| | | |
0100 0000 0000 1000 0000 0110 0000 0001
|| | |
1 -511
What I did so far is:
public static int packSnorm3x10_1x2(float[] v) {
int[] tmp = new int[4];
tmp[0] = (int) (Math.max(-1, Math.min(1, v[0])) * 511.f);
tmp[1] = (int) (Math.max(-1, Math.min(1, v[1])) * 511.f);
tmp[2] = (int) (Math.max(-1, Math.min(1, v[2])) * 511.f);
tmp[3] = (int) (Math.max(-1, Math.min(1, v[3])) * 1.f);
int[] left = new int[4];
left[0] = (tmp[0] << 22);
left[1] = (tmp[1] << 22);
left[2] = (tmp[2] << 22);
left[3] = (tmp[3] << 30);
int[] right = new int[4];
right[0] = (left[0] >> 22);
right[1] = (left[1] >> 12);
right[2] = (left[2] >> 2);
right[3] = (left[3] >> 0);
return right[0] | right[1] | right[2] | right[3];
}
tmp is [-511,-511,0,1], left is [-2143289344,-2143289344,0,1073741824], which in binary is:
[1000 0000 0100 0000 0000 0000 0000 0000,
1000 0000 0100 0000 0000 0000 0000 0000,
0000 0000 0000 0000 0000 0000 0000 0000,
0100 0000 0000 0000 0000 0000 0000 0000]
And it makes sense so far. Now that I cleaned the value on the left, I want to drag them on the right at their right place. But when I do so, I get the gap on the left filled with 1s, I guess because of the signed int in java(?).
Then right is [-511,-523264,0,1073741824] or:
[1111 1111 1111 1111 1111 1110 0000 0001,
1111 1111 1111 1000 0000 0100 0000 0000,
0000 0000 0000 0000 0000 0000 0000 0000,
0100 0000 0000 0000 0000 0000 0000 0000]
So, why is this happening and how can I fix this? Maybe with ANDing only the bits I am interested in?
The unsigned right shift operator >>> shifts a zero into the leftmost position.
Source: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
struct
{
int x : 10;
int y : 10;
int z : 10;
int w : 2;
} data;
This code is completely non-portable, that is, if it even works as expected on your current system.
There is absolutely no way for you to tell what this struct will contain. You can't know what is MSB, you can't know how signedness will be treated, you can't know the endianess, you can't know if there will be padding etc etc. See this.
The only portable solution is to use a raw uint32_t and shift values into place.
Hello i had task from my book to write this code
public class EkspKonverzija
{
public static void main(String args[])
{
byte b;
int i=257;
double d= 323.142;
b=(byte) i;
System.out.println("i and b "+i+" "+b);
i=(int) d;
System.out.println("d and i "+d+" "+i);
b=(byte) d;
System.out.println("b and d "+b+" "+d);
}
}
And result is:
i and b 257 1
d and i 323.142 323
d and b 323.142 67
I understand why the result of first conversion is 1, and i also understand the second conversion, but i dont undetsand why is result 67 at last conversion, i cant figure it out so i need your help. Thanks
All of these are called Narrowing Primitive Conversion (ยง5.1.3):
The conversation to (byte):
257 = 0000 0001 0000 0001
Truncating the high byte gives:
(byte) 257 = xxxx xxxx 0000 0001
which is obviously 1.
The conversation from a floating point to an integer is always round to zero.
The conversation from double to byte happens in two steps:
The double gets casted to an int, following the round to zero rule.
(int) 323.142 ~~~> 323
The int gets truncated to a byte.
(byte) 323 ~~~~> 67
323 = 0000 0001 0100 0011
(byte) 323 = xxxx xxxx 0100 0011
= 67
In Java, Integers must be between 2^31 - 1 through -2^31
so if int x = 2 * 1500000000
The logical answer will be 300000000 but because it has a limit on its value, it is thus brought forward and using 2^32 mod 3000000000 it will be -1294967296 but because it is brought forward the number will become negative because the positive field is overflown. Am i right to say that this is true?
Also, I have search and read up on the modulation part, for e.g. in a clock
15 mod 12 == 3 because it is the remainder of the division however it is good as an example for a clock because 12 is a constant here.
So is 2^32 is the constant of all modulation computation of integers for overflow?
I am going to use 8-bit integers for simplicity.
In binary, 8 bit ranges from 00000000b to 11111111b.
00000000b = 0d
11111111b = 255d
So how do computer add signs to an integer? It's two's complement.
For unsigned integer, we convert 11111111b from binary to denary by this way:
11111111b
= 1*2^7 + 1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0
= 1*128 + 1*64 + 1*32 + 1*16 + 1*8 + 1*4 + 1*2 + 1*1
= 255d
So how about signed integer 11111111b? Here is a simple way:
v----------(sign flag 1=negative)
11111111b
= 1*(-2^7) + 1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0
= 1*(-128) + 1*64 + 1*32 + 1*16 + 1*8 + 1*4 + 1*2 + 1*1
= -1d
In general, the most significant bit of a signed number is the sign flag.
To convert negative denary number to two's complement:
-18d
========
without sign 0001 0010
one's complement 1110 1101 (inverted)
*two's complement 1110 1110 (one's complement + 1)
The range of a 8-bit signed integer is from -2^7 to 2^7-1.
Now what is overflow? Let's see:
01111111b
= 127d
01111111b + 1
= 10000000b
= 1*(-2^7) + 0*2^6 + 0*2^5 + 0*2^4 + 0*2^3 + 0*2^2 + 0*2^1 + 0*2^0
= 1*(-128) + 0*64 + 0*32 + 0*16 + 0*8 + 0*4 + 0*2 + 0*1
= -128d
127d + 1d
=========
0111 1111 (127d) +
+0000 0001 (1d) +
----------
1000 0000 (-128d) - (overflow)
So if we add 1 to the largest 8-bit signed integer, the result is the smallest 8-bit signed integer. +ve + +ve -> -ve is an overflow error.
How about subtractions? 45-16? (+ve + -ve -> +ve)
45d - 16d
=========
0010 1101 (45d) +
+1111 0000 (-16d) -
----------
1 0001 1101 (29d) +
^---------------------(discard)
How about 45-64? (+ve + -ve -> -ve)
45d - 64d
=========
0010 1101 (45d) +
+1100 0000 (-64d) -
----------
1110 1101 (-19d) -
How about -64-64? (-ve + -ve -> -ve)
-64d - 65d
=========
1100 0000 (-64d) -
+1100 0000 (-64d) -
----------
1 1000 0000 (-128d) +
^---------------------(discard)
How about -64-65?
-64d - 65d
=========
1100 0000 (-64d) -
+1011 1111 (-65d) -
----------
1 0111 1111 (127d) + (underflow)
^---------------------(discard)
So -ve + -ve -> +ve is an underflow error.
The situation is similar for 32-bit integers, just more bits available.
For your question 2*1500000000, if we treat them as 32-bit unsigned integer, the result is 3000000000 and its binary representation is:
1011 0010 1101 0000 0101 1110 0000 0000
= 1*2^31 + 0*2^30 + ...
= 1*2147483648 + 0*1073741824 + ...
= 3000000000d
But if we treat it as a 32-bit signed integer:
v------(Let's recall this is the sign flag)
1011 0010 1101 0000 0101 1110 0000 0000
= 1*(-2^31) + 0*2^30 + ...
= 1*(-2147483648) + 0*1073741824 + ...
= -1294967296d
ADDED: Overflow of unsigned integer
The overflow of unsigned integer is quite similar:
11111111b
= 255d
11111111b + 1
= 00000000b
= 0d
255d + 1d
=========
1111 1111 (255d) +
+0000 0001 (1d) +
----------
1 0000 0000 (0d) - (overflow)
^---------------------(discard)
That's why for 32-bit unsigned integers it is always mod 2^32.
And BTW, this is not only for Java, but for most programming languages like C/C++. Some other programming languages may automatically handle overflow and change type to a higher precision or to floating point, like PHP/JavaScript.
You should be modding by 2^32, not 2^31, and then you should be taking into account the signed arithmetic: numbers higher than 2^31 get 2^32 subtracted from them.
Anyway, 2 * 1500000000 = 3000000000 is less than 2^32, but greater than 2^31, so it gets 2^32 subtracted to get -1294967296.