Can anybody please explain what is happening below;how does the following bit shift works?
Dim pBuffer(11) As Int
pBuffer(0)=4
'Firmware Version'
pBuffer(1)=Bit.ShiftRight(Bit.And(firmware_version, 0xFF00),8)
pBuffer(2)=Bit.And(firmware_version, 0xFF)
Consider firmware_version = 0001
What will be the equivalent java code for this? Can I use Bit.ShiftRight in java? I checked the Java classes and didnt quite understand what will be the equivalent 'Bit.ShiftRight' operation in java?
EDIT: Can you explain what exactly is happening here?
pBuffer(1)=Bit.ShiftRight(Bit.And(firmware_version, 0xFF00),8)
How is the AND performed and the bit shift? What is it performed on? Is firmware_version AND 0xFF00 or is it bit shift first? Can you please explain?
in java, you can use the operators >> and >>> for signed and zero-filled right shift, respectively.
Bit-wise and is achieved in Java by &.
See http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
The VB statement
pBuffer(1)=Bit.ShiftRight(Bit.And(firmware_version, 0xFF00),8)
Can therefore by achieved in Java like
pBuffer[1]= (firmware_version & 0xFF00) // Bit.And
>> 8 // shift right 8 bits
VB.NET: Bit.ShiftRight(Bit.And(firmware_version, 0xFF00),8)
(Bitwise-and of firmware_version and 0xFF00 is shifted right 8 times)
Java : (firmware_version & 0xFF00) >> 8 //or >>> for unsigned right-shift
VB.NET: Bit.And(firmware_version, 0xFF)
Bitwise And of firmware_version with 0xFF
Java : (firmware_version & 0xFF)
The & operator in Java performs a bitwise AND operation.
(Reference)
Related
I have this code in Objective-C and I want to write it in Java. However there is the statement (-(crc & 1)) that gives me problems. After some googeling it seems that the negative of an unsigned is generally not well defined. I didn't quite understand it though. Maybe somebody who knows CRC can tell me what the equivalent in Java would be.
I need exactly an equivalent method as a device with this Objective-C code checks my calculated crc against its self calculated.
+ (UInt32) crc32:(UInt32) crc ofByte: (UInt8) byte
{
int8_t i;
crc = crc ^ byte;
for (i = 7; i >= 0; i--)
{
crc = (crc >> 1) ^ (0xedb88320ul & (-(crc & 1)));
}
return(crc);
}
The solved code with help of comments. Seems like I searched the mistake in the wrong place.
private void addByteToCRC(byte oneByte) {
crc ^= oneByte & 0xFF;
for (int i = 7; i >= 0; i--)
{
crc = (crc >>> 1) ^ (0xedb88320 & (-(crc & 1)));
}
}
Both checksums start of with a crc value of 0xFFFFFFFF.
The -(crc & 1) works fine, and is not your problem. What it does is to copy the low bit of crc to all of the bits, since in two's complement representation, –1 is all ones.
There are two things you need to fix for Java, which does not have unsigned integers. First is that the right shift needs to be a logical right shift, >>>. That avoids copying the sign bit when shifting down, and instead shifts in a zero bit. Second, you need to guard against a character being signed-extended to an int, so byte (which will need a different name in Java) needs to be anded with 0xff. So:
crc ^= octet & 0xff;
and
crc = (crc >>> 1) ^ (0xedb88320ul & (-(crc & 1)));
There are some differences between (Objective-)C and Java, but at a guess you may have identified the wrong problem. Java does not have unsigned integer types. However it does have bitwise operators which treat integers as just strings of bits, and later versions of Java do have unsigned operators which when applied to integers operate on the underlying bit patterns as though they represented unsigned values.
The expression crc & 1 will yield a result of 0 or 1 depending on whether crc was even or odd.
The expression -(crc & 1) therefore evaluates to 0 or -1. The bit pattern of 0 is all zeros and for -1 it is all ones - the latter is true in (Objective-)C regardless of the underlying representing of integers as 1's or 2's complement, see Is it safe to use -1 to set all bits to true? for an explanation.
The expression 0xedb88320ul & (-(crc & 1)) therefore evaluates to 0 or 0xedb88320.
The expression crc >> 1 is the logical, or unsigned, shift right in (Objective-)C as src is defined as unsigned (right shifts for signed integers are "implementation defined" in (Objective-)C).
The expression x ^ 0 for any x evaluates to x.
Put that all together and your whole expression (crc >> 1) ^ (0xedb88320ul & (-(crc & 1))) conditionally xors crc >> 1 with 0xedb88320 base don whether crc is odd or even.
Now you just need to reproduce the same behaviour in Java.
Java uses 32-bit 2's complement integers for int (JLS: Primitive Types and Values) and provides bitwise operators which treat them as just bit-strings.
The hexadecimal constant comes just 0xedb88320 and has int (32-bit) type.
The expression -(crc & 1) therefore evaluates as in (Objective-)C.
However the expression crc >> 1 will not evaluate the same as in (Objective-)C. In Java the >> is an arithmetic shift right, which replicates the sign-bit during the shift. This choice stems from Java using signed types. Fortunately Java also provides the >>> operator to perform a logical, or unsigned, right-shift.
So my guess is you may have identified the wrong problem in your conversion and you need to use the >>> operator.
HTH
I hate myself to ask this question, but i couldn't find any solution anywhere.
(byte) ((localIntBuffer[srcIdx + col] >> 8) & 0xFF)
This code writed with Java, and i would like to learn equals in Delphi and what is the meaning of this code?
The >> operator is signed right shift.
The & operator is bitwise and.
The (byte) is a cast to byte.
The [] is the array indexing operator.
In Delphi this would be written like this:
(localIntBuffer[srcIdx + col] shr 8) and $ff
There's no need for a cast in Delphi because all integral types are assignment compatible and the and $ff ensures that the value is in the correct range.
The distinction between signed shift and unsigned shift is not important here because you are picking out bits 8-15 from a 32 bit signed integer. Well, I presume that localIntBuffer is an array of int. It would have better had you said so rather than leaving us to guess. It is a very common novice mistake to believe that code alone suffices. Invariably knowledge of types is crucial too.
As #TLama correctly points out, it pays to consult the documentation:
Java operators: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/opsummary.html
Delphi operators: http://docwiki.embarcadero.com/RADStudio/en/Expressions_%28Delphi%29#Operators
Another way to write this would be to use LongRec from SysUtils to pick out the desired byte:
LongRec(localIntBuffer[srcIdx + col]).Bytes[1]
I'm writing code in Java using short typed variables. Short variables are normally 16 bits but unfortunately Java doesn't have unsigned primitive types so I'm using the 15 lower bits instead ignoring the sign bit. Please don't suggest changes to this part as I'm already quite far in this implementation... Here is my question:
I have a variable which I need to XOR.
In C++ I would just write
myunsignedshort = myunsignedshort ^ 0x2000;
0x2000 (hex) = 0010000000000000 (binary)
However, in Java, I have to deal with the sign bit also so I'm trying to change my mask so that it doesn't affect the xor...
mysignedshort = mysignedshort ^ 0xA000;
0xA000 (hex) = 1010000000000000 (binary)
This isn't having the desired effect and I'm not sure why. Anyone can see where I'm going wrong?
Regards.
EDIT: ok you guys are right, that bit wasn't causing the issue.
the issue comes when I'm shifting bits to the left.
I accidentally shift bits into the sign bit.
mysignedshort = mysignedshort << 1;
Any any ideas how to avoid this new prob so that if it shifts into the MSB then nothing happens at all? or should I just do a manual test? Theres a lot of this shifting in the code though so I would prefer a more terse solution.
Regards.
Those operations don't care about signedness, as mentioned in the comments. But I can expand on that.
Operations for which the signed and unsigned versions are the same:
addition/subtraction
and/or/xor
multiplication
left shift
equality testing
Operations for which they are different:
division/remainder
right shift, there's >> and >>>
ordered comparison, you can make a < b as (a ^ 0x80000000) < (b ^ 0x80000000) to change from signed to unsigned, or unsigned to signed.
You can also use (a & 0xffffffffL) < (b & 0xffffffffL) to get an unsigned comparison, but that doesn't generalize to longs.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Java's >> versus >>> Operator?
Hi,
I know >> or << can improve the performance , but what's the purpose about >>> operator ?
ex PriorityQueue class in JDK source file,
private void heapify() {
for (int i = (size >>> 1) - 1; i >= 0; i--)
siftDown(i, (E) queue[i]);
}
Don't tell me how >>> works , just why I use it .
Thank you
The >> operator preserves the left most bit, but >>> does not.
This means if you shift a negative number with >> it stays negative, but if you use >>> it does not.
So use >> for mathematic operations, and >>> for bit bases operations.
Use <<, >> and >>> for operations on integral types that represent bit patterns.
DO NOT use them to "speed up" multiplication and division. The chances are that it won't make any difference, and it may actually make your code slower.
The Java JIT compiler should be capable of generating machine code for simple arithmetic expressions that is optimal for the hardware that it is currently running on.
If you implement your arithmetic using clever masking and shifting, there is a chance that 1) the code won't be optimal for the machine you are running on, 2) the JIT optimizer won't figure out that you are actually doing arithmetic ... and therefore won't be able to optimize. The end result will be slower code.
Difference between >> and >>> operators is that >> is for unsigned shift. It means that >>> clears most left bit when >> preserves value of this bit (because in fact this bit means negative value)
Example:
you have value FFFFFFFEh = -2 (signed) then:
-2 >> 1 = FFFFFFFF = -1 // >> preserves highest bit value; note, this wrong if we treat FFFFFFFF as unsigned value
-2 >>> 1 = 7FFFFFFF // >>> clears highest bit
so if you want to operate with unsigned values you should use >>> instead of >>.
In converting from short to a byte array I found the following solution on the web but could not quite understand the logic involved.
//buffer is an array of bytes, bytes[]
buffer[position] = (byte)(sample & 0xff);
buffer[position+1] = (byte)((sample >> 8) & 0xff);
Can someone tell me why 0xff (256) is being anded to the sample which is a short?
This code probably comes from C code (or was written by a C programmer who don't parse Java as well as erickson does). This is because in Java a cast from a type with more information to a type with less information will discard the higher order bits and thus the & 0xff is unnecessary in both cases.
A short has 16 bits, two bytes. So it needs to take two slots in the byte array, because if we just casted a short into a byte one byte would be lost.
So, the code you have does
1110001100001111 sample
0000000011111111 0xff
0000000000001111 sample & 0xff => first byte`
Then, displaces the sample to get the second byte
0000000011100011 sample >> 8
0000000011111111 0xff
0000000011100011 (sample >> 8 ) & 0xff => second byte
Which can be a lot better written as erickson shows below (hopefully it'll be above soon).
The other answers have some good information, but unfortunately, they both promote an incorrect idea about the cast to byte.
The & 0xFF is unnecessary in both cases in your original code.
A narrowing cast discards the high-order bits that don't fit into the narrower type. In fact, the & 0xFF actually first causes the short to be promoted to an int with the most significant 24 bits cleared, which is then chopped down and stuffed in a byte by the cast. See the Java Language Specification Section §5.1.3 for details.
buffer[position] = (byte) sample;
buffer[position+1] = (byte) (sample >>> 8);
Also, note my use of the right shift with zero extension, rather than sign extension. In this case, since you're immediately casting the result of the shift to a byte, it doesn't matter. In general, however, the operators give different results, and you should be deliberate in what you choose.
It makes sure there's no overflow; specifically, the first line there is taking the LSByte of "sample" and masking OUT your upper 8 bits, giving you only values in the range of 0-255; the second line there is taking the MSByte of "sample" (by performing the right-shift) and doing the same thing. It shouldn't be necessary on the second line, since the right-shift by 8 should drop out the 8 least significant bits, but it does make the code a little bit more symmetric.
I would assume that this is because since sample is a short (2 bytes) any values in the range of 256-6553 would be interpreted as 255 by the byte conversion.
buffer[position] = (byte)(sample & 0xff);
buffer[position+1] = (byte)((sample >> 8) & 0xff);
must be :
buffer[position] = (byte)((sample >> 8) & 0xff);
buffer[position+1] = (byte)(sample & 0xff);