1

I am trying to write a Java equivalent for a function in C#. The code follows.

In C#:

byte[] a = new byte[sizeof(Int32)];
readBytes(fStream, a, 0, sizeof(Int32)); //fstream is System.IO.Filestream
int answer = BitConverter.ToInt32(a, 0);

In Java:

InputStream fstream = new FileInputStream(fileName);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
byte[] a = new byte[4];
readBytes(in, a, 0, 4);
int answer = byteArrayToInt(a);

Both Java and C#:

int readBytes(Stream stream, byte[] storageBuffer, int offset, int requiredCount)
        {
            int totalBytesRead = 0;
            while (totalBytesRead < requiredCount)
            {
                int bytesRead = stream.Read(
                                storageBuffer,
                                offset + totalBytesRead,
                                requiredCount - totalBytesRead);
                if (bytesRead == 0)
                {
                    break; // while
                }

                totalBytesRead += bytesRead;
            }

            return totalBytesRead;
        }

Output:

In C#: answer = 192  (Correct)  
In JAVA: answer = -1073741824 

There is a difference in the two.I am reading from a file input stream which is encoded and parsing the first four bytes. The C# code seems to produce 192 which is the correct answer while Java produces -1073741824 which is the wrong answer. Why and how ?

EDIT

Here is my byteArrayToInt

public static int byteArrayToInt(byte[] b, int offset) {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (4 - 1 - i) * 8;
            value += (b[i + offset] & 0x000000FF) << shift;
        }
        return value;
    }

SOLUTION The right solution for byteArrayToInt

public static int byteArrayToInt(byte[] b) 
    {
        long value = 0;
        for (int i = 0; i < b.length; i++)
        {
           value += (b[i] & 0xff) << (8 * i);
        }
        return (int) value;
    }

This gives the right output

2 Answers 2

10

In java bytes are signed, so your -64 in java byte is binary equivalent to 192 in c# byte (192 == 256 - 64).

The problem is probaby in byteArrayToInt() where you assume it's unsigned during the conversion.

A simple

 `b & 0x000000FF`

might help in that case.

Sign up to request clarification or add additional context in comments.

4 Comments

I ve edited to include my byteArrayToInt - is this right ? What am I missing
@Vrashabh you're not missing anything. it returns 192 for byte array {0, 0, 0, -64} and offset == 0
Sorry another edit . Here are my outputs . C#: Before bit conversion a = {192,0,0,0} and after conversion a=192 Java: Before bit conversion a = {-64,0,0,0} and after a = -1073741824
Thanks for putting me on the right track. Changed my byteArrayToInt (see edit)
2

Java's byte object is signed as soulcheck wrote. The binary value for 192 on an unsigned 8 bit integer would be 11000000.

If you are reading this value with a signed format, a leading 1 will indicate a negative. This means 11000000 becomes negative 01000000, which is -64.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.