Solved

Overflow errors in byte conversion testing?

Posted on 2007-11-19
15
154 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
How to convert String matching to regex in java 4 50
by zero exception 10 52
Java 8 to Java 6 8 20
American Express @Work site and Java 4 27
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…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
The viewer will learn how to implement Singleton Design Pattern in Java.

838 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