Results 1 to 11 of 11
Like Tree3Likes
  • 1 Post By jim829
  • 1 Post By Norm
  • 1 Post By jim829

Thread: Converting two octets representing the year into an integer: wrong value

  1. #1
    igorland is offline Member
    Join Date
    Jan 2013
    Posts
    89
    Rep Power
    0

    Default Converting two octets representing the year into an integer: wrong value

    Hello.

    I have a dataset with binary data that I need to convert to text or integers. The binary data is represented by octets.

    I am reading the data into an array of bytes:

    Java Code:
    MainClass binary = new MainClass();
    byte[] bytes = binary.readSmallBinaryFile(FILE_NAME);
    
    
    byte[] readSmallBinaryFile(String aFileName) throws IOException 
    {
       Path path = Paths.get(aFileName);
       return Files.readAllBytes(path);
    }
    I know that the first 4 octets represent the word "GRIB". I do that without a problem. The problem starts when I have large numbers.

    I know that octets 29 and 30 should show the current year. When I read the bytes:

    Java Code:
    System.out.println("YEAR: " + bytes[28] + bytes[29]);
    I get this:

    YEAR: 7-32

    I understand that the bytes are signed in Java, so I should probably convert them to unsigned or short to get the current year, i.e. 2016.

    When I do this:

    Java Code:
    public static int unsignedToBytes(byte b) {
       return (int) b & 0xFF;
     }
    My output is: 7224

    When I do this:

    Java Code:
    public static int convertTwoBytesToInt2(byte b1, byte b2) {
      return (int) (( (b2 & 0xFF) << 8) | (b1 & 0xFF));
    }
    My output is: 57351

    Am I missing anything in the byte conversion? The data should have no erros.

    Thank you!

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    14

    Default Re: Converting two octets representing the year into an integer: wrong value

    It is impossible to make a primitive type unsigned in Java. The sign bit will always be there and used when comparing values.
    If you want some help in doing proper conversions from say, byte values to their normal int values, then you need to provide:

    1. The values that you are reading and what you are assigning them too.
    2. The position of the bytes (e.g. highorder - left most, to loworder - right most)
    2. And the resultant value that you want to display or use.

    You might also be better served by using a DataInputStream for reading the input.

    Regards,
    Jim
    igorland likes this.
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  3. #3
    igorland is offline Member
    Join Date
    Jan 2013
    Posts
    89
    Rep Power
    0

    Default Re: Converting two octets representing the year into an integer: wrong value

    Hello, Jim. Firstly, thanks a lot for trying to help. I am stuck with this problem for several weeks already.

    Quote Originally Posted by jim829 View Post
    You might also be better served by using a DataInputStream for reading the input.
    Fixed. Use DataInputStream now. Code is standard, so I thought I would not waste your time by including it here. The file is read just fine.

    Quote Originally Posted by jim829 View Post
    ...you need to provide:
    1. The values that you are reading and what you are assigning them too.
    2. The position of the bytes (e.g. highorder - left most, to loworder - right most)
    2. And the resultant value that you want to display or use.
    1. I tried to get the values that I am reading by using this:
    Java Code:
    System.out.println("MONTH BIN: " + Integer.toBinaryString(buf[30]));
    System.out.println("MONTH: " + buf[30]);
    System.out.println("DAY BIN: " + Integer.toBinaryString(buf[31]));
    System.out.println("DAY: " + buf[31]);
    
    System.out.println("YEAR1 BIN: " + Integer.toBinaryString(buf[28]));
    System.out.println("YEAR1: " + buf[28]);
    System.out.println("YEAR2 BIN: " + Integer.toBinaryString(buf[29]));
    System.out.println("YEAR2: " + buf[29]);
    This is the output I have:
    Java Code:
    MONTH BIN: 1010
    MONTH: 10
    DAY BIN: 1010
    DAY: 10
    YEAR1 BIN: 111
    YEAR1: 7
    YEAR2 BIN: 11111111111111111111111111100000
    YEAR2: -32
    As you may see, the Month and Day are converted just fine (October 10). The year is not. I know from the binary file documentation that these two octets must represent the current year. Should it be "20""16", I am not sure.

    2) This is interesting. I have done a lot of research, and some sources say that this binary data should be endian independent, and some say it is big endian. Is this what you meant?

    3) As I said previously, the value I should get is the current year, i.e. 2016.

    Thank you so much for your help!

  4. #4
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    20,003
    Rep Power
    33

    Default Re: Converting two octets representing the year into an integer: wrong value

    What is your defintion of an "octet"?
    Can you post the definition of the buf array variable?

    A byte can hold 256 different values. No way it can hold 2016. Are you sure your definition of the contents of the array is correct?

    the Month and Day are converted just fine (October 10)
    Binary digits are 0 and 1. There are very few dates that only use those 2 digits. October 10 is one. November 11 another.
    Integer.toBinaryString() will only output 0s and 1s
    If you don't understand my response, don't ignore it, ask a question.

  5. #5
    igorland is offline Member
    Join Date
    Jan 2013
    Posts
    89
    Rep Power
    0

    Default Re: Converting two octets representing the year into an integer: wrong value

    Quote Originally Posted by Norm View Post
    What is your defintion of an "octet"?
    Can you post the definition of the buf array variable?
    A byte can hold 256 different values. No way it can hold 2016. Are you sure your definition of the contents of the array is correct?
    Binary digits are 0 and 1. There are very few dates that only use those 2 digits. October 10 is one. November 11 another.
    Integer.toBinaryString() will only output 0s and 1s
    Norm. Thank you.
    My definition of an "octet" is a byte. This is just the term used in the binary data format documentation.
    I am aware that binary digits are 0 and 1. If you see my response, the binary representation of the Day and Month is "1010", which corresponds to decimal "10". So, in this case the Day and Month are represented by binary "1010" "1010" and decimal "10" "10".

    I am also aware that a byte is 256. Therefore, in this case the year is represented by 2 bytes: buf[28] and buf[29]. So most likely, buf[28] should equal "20" and buf[29] is "16". But I am not sure. (Other options, like "2" "016" or "201" "6" are unlikely, in my opinion). I know for sure the two bytes should read "2016".

    I know that Integer.toBinaryString() will only output 0s and 1s. I just wanted to show you the binary data that I am receiving from the file.

    Thank you,

    Igor

  6. #6
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    20,003
    Rep Power
    33

    Default Re: Converting two octets representing the year into an integer: wrong value

    the year is represented by 2 bytes: buf[28] and buf[29].
    Perhaps the two bytes need to be put together to make a single 16 bit number: 8 bits from one and 8 from the other. Then that number displayed as decimal digits.
    To put two bytes together, shift one byte left 8 bits and add in the other one.
    igorland likes this.
    If you don't understand my response, don't ignore it, ask a question.

  7. #7
    igorland is offline Member
    Join Date
    Jan 2013
    Posts
    89
    Rep Power
    0

    Default Re: Converting two octets representing the year into an integer: wrong value

    Norm!!!

    Did the following:
    Java Code:
    int val = ((buf[28] & 0xff) << 8) | (buf[29] & 0xff);
    and got 2016.

    Thank you so much!

    The only question I have is whether, in your opinion, the above code is good enough and will correctly work in all possible situations.

    Thank you, guys!

    Igor

  8. #8
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    14

    Default Re: Converting two octets representing the year into an integer: wrong value

    Norm's suggestion is correct (and your earlier static method works). You just mixed up the high and low bytes of the low order 16 bits.

    Regards,
    Jim
    igorland likes this.
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  9. #9
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    14

    Default Re: Converting two octets representing the year into an integer: wrong value

    It should. However, a simple test is the way to go. Generate all values from 0 to 65535. Then
    grab the low order byte with an 0xFF mask, then shift that right and mask again. Then take those
    two bytes and pass them to your method and compare the result to the original value.

    Where practical, testing of this sort or at least with border cases is worthwhile.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  10. #10
    igorland is offline Member
    Join Date
    Jan 2013
    Posts
    89
    Rep Power
    0

    Default Re: Converting two octets representing the year into an integer: wrong value

    Thanks again for your help! Case closed!

  11. #11
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    20,003
    Rep Power
    33

    Default Re: Converting two octets representing the year into an integer: wrong value

    Note: Here's a test I did to see what the data was:
    Java Code:
     System.out.println(Integer.toHexString(2016)); // 07e0 -> 0000 0111 1110 0000
    If you don't understand my response, don't ignore it, ask a question.

Similar Threads

  1. Converting a String to Integer
    By Diyanosh in forum New To Java
    Replies: 6
    Last Post: 09-25-2014, 06:53 PM
  2. converting binary to integer
    By Olive in forum New To Java
    Replies: 2
    Last Post: 09-08-2014, 06:20 AM
  3. Converting string to integer
    By Thibisan in forum New To Java
    Replies: 5
    Last Post: 05-18-2012, 11:10 AM
  4. Converting J001 to integer
    By jaylimix in forum New To Java
    Replies: 4
    Last Post: 12-15-2011, 11:08 PM
  5. Converting an integer into a BigInteger
    By mzjazzygirl in forum New To Java
    Replies: 27
    Last Post: 09-23-2010, 06:37 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •