Solved

Overflow errors in byte conversion testing?

Posted on 2007-11-19
15
155 Views
Last Modified: 2010-03-30
I have a JUnit test that passes in a byte[] to a method which offsets and ANDs the values, converts them to a hex string and appends it to the result. The test consistently fails when I pass in 128, -1 and other values. The bytes that will be passed in will be randomly generated so it's important that they are consistently converted correctly and not just for some values.


import junit.framework.TestCase;

public class UtilsTest extends TestCase
{

      public UtilsTest(String name)
      {
            super(name);
      }

      protected void setUp() throws Exception
      {
            super.setUp();
      }

      protected void tearDown() throws Exception

      public final void testConvertByteArray()
      {
            byte[] byteTestArr={Byte.MIN_VALUE, -1, 0, 1, 5, Byte.MAX_VALUE};      //total: 6
                              //-128                        127

            byte[] byteTestArrMin={Byte.MIN_VALUE};
            byte[] byteTestArrMinus1={-1};

            result=Utils.convertByteArray(byteTestArrMin);
            assertEquals("80", result);
            //FAILS +128=0x80 so should this be -80?
            
            result=Utils.convertByteArray(byteTestArrMinus1);
            assertEquals("-1", result);
            //FAILS returns ff = 255
            
            result=Utils.convertByteArray(byteTestArr);
            assertEquals("6", result);
            //FAILS actual: 80ff0001057f
      }
}


      public static String convertByteArray(byte[] bytes)
      {
            String strResult="";

            for (int i = 0; i < bytes.length; ++i)
            {
                  strResult+=Integer.toHexString(0x0100 + (bytes[i] & 0x00FF)).substring(1);
            }
            
            return strResult;
      }
0
Comment
Question by:mark_667
  • 7
  • 4
  • 4
15 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 20313932
>>assertEquals("80", result);

should be

assertEquals("ff", result);
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 20313935
Sorry - forget that
0
 
LVL 37

Accepted Solution

by:
gregoryyoung earned 125 total points
ID: 20314310
I am just curious ...

what  is the point of bytes[i] & 0x00FF

you are anding a byte to 0xFF ?!?! this has no effect as its already a byte (FF=255)



why are you then adding the value 0x0100 + (bytes[i] & 0x00FF) converting to hex then removing the leading character (the 1)? I guess I am really confused here as to your goal with this code (especially when dealing with signs as ToHexString http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Integer.html#toHexString(int) will give you the unsigned value)

What is it you are hoping to do here? Just convert the byte to hex?

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:mark_667
ID: 20318813
gregoryyoung: Yes, I'm trying to a convert a byte[] to a String containing the equivalent hex values but it's harder than it sounds.

Lets give the 2 versions the same input and see how they perform:
byte[]={-106, 106}      //these are just random values

      public static String convertByte(byte[] bytes)
      {
            String strResult="";
            for (int i = 0; i < bytes.length; ++i)
            {
                  strResult+=Integer.toHexString(0x0100 + (bytes[i])).substring(1);
            }

            return strResult;
      }


i=0 strResult=6
i=1 strResult=66a

answer=66a(hex) in decimal this should be 38506(966A hex) not 1642


      public static String convertByte(byte[] bytes)
      {
            String strResult="";
            for (int i = 0; i < bytes.length; ++i)
            {
                  strResult+=Integer.toHexString(0x0100 + (bytes[i] & 0x00FF)).substring(1);
            }

            return strResult;
      }

i=0 strResult=96
i=1 strResult=996a

correct

I tried the method in the link you gave but can't seem to make it work. I tried:

      public static String convertByte(byte[] bytes)
      {
            Byte b = Byte.decode(bytes.toString());                  //convert byte[] to String to Byte
            //is there a better way of converting a byte[] to an int?
            strResult=Integer.toHexString(b.intValue());      //get the intValue of the Byte
            
            return strResult;
      }

gives a result of "B@11f2ee1" is this what you meant? Can you provide an example please?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 20320836
>>
Lets give the 2 versions the same input and see how they perform:
byte[]={-106, 106}      //these are just random values
>>

...

>>answer=66a(hex) in decimal this should be 38506(966A hex) not 1642

No. Answer = 966a. Those are two separate hex representations of bytes in the array. Let's establish this as a fact first, since i don't understand your comment about 'in decimal'
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 20321369
"Yes, I'm trying to a convert a byte[] to a String containing the equivalent hex values but it's harder than it sounds."

OK ... let's forget about the code you have written and focus on how to solve the problem ... how do you want to handle signing? (or are you not interested in it)

Cheers,

Greg
0
 
LVL 1

Author Comment

by:mark_667
ID: 20326633
CEHJ: I think you misunderstood me I know 996a is the right result, my point was that the Integer.toHexString(int) method I posted only gives 66a. I thought the substringing might be causing problems so I removed it and tried:
strResult+=Integer.toHexString(0x0100 + (bytes[i] & 0x00FF));
gives 1663338 ???
strResult+=Integer.toHexString(bytes[i]); also gives the same result.

gregoryyoung: have no idea about signing, just want to keep it as simple as possible.

thanks for the responses
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 20326661
>>
CEHJ: I think you misunderstood me I know 996a is the right result, my point was that the Integer.toHexString(int) method I posted only gives 66a.
>>

No. My point was not that it should be 996a, but that it *is* 996a. I'm running it and that's what it gives me
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 20329442
mark: signing is referring to the difference between positive and negative numbers ... in binary a number that is negative has the first bit set ... (in other words in a byte ...)

1 is ...   0000 0001 = 0x01
-1 is ...  1000 0001 = 0x81

So I am curious of how you want to handle this case? Do you just want to print unsigned hex up? If so thats what Integer.ToHexString() already does...

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 20339570
mark_667: can you tell us why you accepted that answer?
0
 
LVL 1

Author Comment

by:mark_667
ID: 20344228
The method with the parameter he specified formed the basis of my best answer to the problem yet. It's a difficult one to choose an answer for as I still don't  really know what was causing the results I mentioned in the OP and I still don't have a perfect solution but I at least now have a solution that gives slightly fewer of them. I can't believe greggoryyoung didn't think I knew what a sign bit is!
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 20344309
"I can't believe greggoryyoung didn't think I knew what a sign bit is!"

mark: its based on this comment...

"gregoryyoung: have no idea about signing, just want to keep it as simple as possible."

When dealing with hex numbers its kind of important :) I was trying to figure out what your requirements were for dealing with signing ...
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 20344443
>>It's a difficult one to choose an answer for as I still don't  really know what was causing the results I mentioned in the OP

Well, the output that you claimed was wrong wasn't wrong. As i mentioned, i ran your code myself and the output was just as to be expected. For some reason, you chose to ignore those comments though
0
 
LVL 1

Author Comment

by:mark_667
ID: 20349468
OK, lets clear this up.

>>i ran your code myself and the output was just as to be expected
what did you run? I ran the original code I posted against the test
result=Utils.convertByteArray(byteTestArrMin);
            assertEquals("ff", result);
but get back 80 in result.

I re-ran the tests for the variations given. Starting with the original code:

import junit.framework.TestCase;

public class UtilsTest extends TestCase
{

      public UtilsTest(String name)
      {
            super(name);
      }

      protected void setUp() throws Exception
      {
            super.setUp();
      }

      protected void tearDown() throws Exception {}

      public final void testConvertByteArray()
      {
            byte[] byteTestArr={Byte.MIN_VALUE, -1, 0, 1, 5, Byte.MAX_VALUE};      //total: 6
                              //-128                        127

            byte[] byteTestArrMin={Byte.MIN_VALUE};
            byte[] byteTestArrMinus1={-1};
            String result="";

            result=Utils.convertByteArray(byteTestArrMin);
            assertEquals("80", result);
            //FAILS +128=0x80 so should this be -80?
           
            result=Utils.convertByteArray(byteTestArrMinus1);
            assertEquals("-1", result);
            //FAILS returns ff = 255
           
            result=Utils.convertByteArray(byteTestArr);
            assertEquals("6", result);
            //FAILS actual: 80ff0001057f
      }
}

public class Utils
{
        public static String convertByteArray(byte[] bytes)
      {
            String strResult="";

            for (int i = 0; i < bytes.length; ++i)
            {
                  strResult+=Integer.toHexString(0x0100 + (bytes[i] & 0x00FF)).substring(1);
            }
           
            return strResult;
      }
}


2nd test fails, expected -1 but was ff.
3rd test fails, expected 6 but was 80ff0001057f.


>>should be

>>assertEquals("ff", result);

for 1st test fails, expected ff but was 80.

try the tests with the new method:
 public static String convertByte(byte[] bytes)
      {
            String strResult="";
            for (int i = 0; i < bytes.length; ++i)
            {
                  strResult+=Integer.toHexString(0x0100 + (bytes[i])).substring(1);
            }

            return strResult;
      }
and a new test:

byte[] newTest={-106,106};
result=Utils.convertByteArray(byteTestArr);
            assertEquals("6", result);

test fails, expected 966a but was 66a

with the original method:
test passes, expected 966a and was 966a

with:
strResult+=Integer.toHexString(0x0100 + (bytes[i] & 0x00FF));

new test fails, expected 966a but was 19616a
1st test fails, expected ff but was 180.
2nd test fails, expected -1 but was 1ff.
3rd test fails, expected 6 but was 1801ff10010110517f

with
strResult+=Integer.toHexString(bytes[i]);

new test fails, expected 966a but was ffffff966a
1st test fails, expected ff but was ffffff80
2nd test fails, expected -1 but was ffffffff
3rd test fails, expected 6 but was ffffff80ffffffff0157f
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 20349535
Let's take this one point at a time:

>>>>
OK, lets clear this up.

>>i ran your code myself and the output was just as to be expected
what did you run? I ran the original code I posted against the test
result=Utils.convertByteArray(byteTestArrMin);
            assertEquals("ff", result);
but get back 80 in result.
>>>>

That's exactly to be expected: 0x80 is the hex representation of byte's minimum value (-128). 0xff is the hex representation of -1
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Article by: Nadia
Linear search (searching each index in an array one by one) works almost everywhere but it is not optimal in many cases. Let's assume, we have a book which has 42949672960 pages. We also have a table of contents. Now we want to read the content on p…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

740 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question