Java (byte) ((localIntBuffer[srcIdx + col] >> 8) & 0xFF) - java

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]

Related

Bitwise shift operation choice

Hello everyone I'm learning programming in java and I wanted to know why is the choice for
Sign bit propagation is ">>" and not ">>>"?
I would assume << and >> should have the same implementation.
Sorry if it sounds like a silly question :)
Thanks in advance!
The reason it works this way is because C and C++ used << for left shift and >> for right shift long before Java. Those languages have both signed and unsigned types, and for signed types the sign bit was propagated in the right-shift case.
Java does not have unsigned types, so they kept the behavior of C and C++ so as not to sow confusion and incur the undying wrath of developers the world over. Then they included >>> to provide a right-shift that treated the bit value as unsigned.
This question is really about reading James Gosling's mind :-). But my guess is that << and >> both make sense mathematically: << causes a number to be multiplied by 2 (barring overflow), and >> causes a number to be divided by 2--when you have sign propagation, this works whether the number is positive or negative. Perhaps the language designers thought this would be a more common use of the right shift than the operator that propagates 0's, which is more useful when integers are treated as strings of bits rather than actual numbers. Neither way is "right" or "wrong", and it's possible that if Gosling had had something different for breakfast that morning, he might have seen things your way instead...
Lets start with the questions that you didn't ask :-)
Q: Why is there no <<<?
A1: Because << performs the appropriate reverse operation for both >> and >>>.
>> N is equivalent to divide by 2N for a signed integer
>>> N is equivalent to divide by 2N for an unsigned integer
<< N is equivalent to multiply by 2N for both signed and unsigned integers
A2: Because the sign bit is on the left hand end, so "extending" it when you shift leftwards is nonsensical. (Rotating would make sense, but Java doesn't have any "rotate" operators. Reasons: C precedent, lack of hardware support in some instruction sets, rotation is rarely needed in Java code.)
Q: Why does only one of >> and >>> to sign extension
A: Because if they both did (or neither did) then you wouldn't need two operators.
Now for your questions (I think):
Q: Why did they choose >> to do sign extension and not >>>?
A: This is really unanswerable. As far as we know, there is no extant publicly available contemporaneous record of the original Oak / Java language design decisions. At best, we have to rely on the memory of James Gosling ... and his willingness to answer questions. AFAIK, the question has not been asked.
But my conjecture is that since Java integer types are (mostly) signed, it was thought that the >> operator would be used more often. In hindsight, I think Gosling et al got that right.
But this was NOT about copying C or C++. In those languages, there is only one right-shift operator (>>) and its behavior for signed integers is implementation defined!!. The >>> operator in Java was designed to fix that problem; i.e. remove the portability problem of C / C++ >>.
(Reference: Section 6.5.7 of the draft C11 Language spec.)
Next your comment:
I would assume << and >> should have the same implementation. By same implementation I mean same process but opposite direction.
That is answered above. From the perspective of useful functionality, >> and << do perform the same process for signed numbers but in different direction; i.e. division versus multiplication. And for unsigned numbers <<< corresponds to >> in the same way?
Why the difference? It is basically down to the mathematics of 2's complement and unsigned binary representations.
Note that you cannot perform the mathematical inverse of >> or >>>. Intuitively, these operators throw away the bits on the right end. Once thrown away, those bits cannot be recovered.
Q: So why don't they make << (or a hypothetical <<<) "extend" the right hand bit?
A: Because:
It is not useful. (I cannot think of any mainstream use-cases for extending the right hand bits of a number.)
There is typically no hardware support (... because it is not useful!)

Negative of UInt8

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

Simple bitwise operation in Java

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.

Bit.ShiftRight - equivalent in java

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)

How to convert a (short) sample in a soundfile to array of bytes

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);

Categories