0

I have few fields in C++ defined and using those fields we are making a new value. I need to do similar things in Java by following C++ method.

  • "text" is defined as uint8_t
  • "client_id" is defined as uint16_t
  • "proc_id" is defined as uint8_t
  • "pod_count" is defined as uint32_t

Below are C++ methods:

typedef uint64_t    ClientData;

// convert all four fields into one variable "client_data"
void pack(uint8_t text, 
          uint16_t client_id, 
          uint8_t proc_id, 
          uint32_t pod_count,
          ClientData& client_data)
{
    client_data = (uint64_t(text) << 56)
                   + (uint64_t(client_id) << 40)
                   + (uint64_t(proc_id) << 32)
                   + pod_count;
}

// now retrieve individual fields value from converted "client_data" variable
void unpack(ClientData client_data,
            uint8_t& text, 
            uint16_t& client_id, 
            uint8_t& proc_id, 
            uint32_t& pod_count)
{
    pod_count = client_data & 0xffffffff;
    client_data = client_data >> 32;
    proc_id = client_data & 0xff;
    client_data = client_data >> 8;
    client_id = client_data & 0xffff;
    client_data = client_data >> 16;
    text = client_data & 0xff;
}

Now this is what I am doing in Java:

public final class ClientData {
  private final byte text;
  private final short clientId;
  private final byte procId;
  private final int podCount;

  // this is my pack method corresponding to c++ method above
  public long pack() {
    return (((long) text) << 56) | (((long) clientId) << 40) | (((long) procId) << 32)
        | ((long) podCount);
  }  

  // this is my unpack in Java.
  public unpack(long packedValue) {
    this.text = (byte) ((packedValue >>> 56) & ((1 << 8) - 1));
    this.clientId = (short) ((packedValue >>> 40) & ((1 << 16) - 1));
    this.procId = (byte) ((packedValue >>> 32) & ((1 << 8) - 1));
    this.podCount = (int) ((packedValue) & ((1L << 32) - 1));
  }
}

Now my question is - Whether the logic that I have in pack and unpack method in Java is correct as per above C++ code? And pod_count in C++ is defined as uint32_t but in my above Java code I have it as int.

1
  • Did you test it yourself? Are you getting any error after that? Commented Jan 15, 2019 at 0:08

1 Answer 1

1

By default, Java has signed numbers but you can use them as unsigned ones. Java Primitive data types.

  • uint8_t: byte is a 8-bit signed integer. If you want to add a sign-bit, you have to use short.
  • uint16_t: short is a 16-bit signed integer. If you want to add a sign-bit, you have to use int.
  • uint32_t: int is a 32-bit signed integer. But, you can use it as an unsigned integer. For that, you might wanna look into the unsigned comparison methods etc.
  • uint64_t: long is a 64-bit signed integer. But, you can use it as an unsigned integer.

I think it does not matter if you are using signed or unsigned of data types are using with the bitwise operators. The only problem you will get it is while printing those numbers or converting them to strings. For that, you can use either toUnsignedInteger method of Byte and Short or toUnsignedLong of Integer.

For the logic part: You can implement the bitwise logic as in C++ but with type casts. Please refer to the documentation for more information.

public class ClientData
{
    private int pod_count;
    private byte proc_id;
    private short client_id;
    private byte text;

    public static void main (String[] args)
    {
        new ClientData().unpack(Long.decode("0x32112321321fdffa"));
    }
    void unpack(long client_data)
    {
        this.pod_count = (int)(client_data & 0xffffffff);
        client_data = client_data >> 32;
        this.proc_id = (byte) (client_data & 0xff);
        client_data = client_data >> 8;
        this.client_id = (short) (client_data & 0xffff);
        client_data = client_data >> 16;
        this.text = (byte) (client_data & 0xff);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

In Java pod_count is defined as int but in C++ it is uint32_t. So what happens if pod_count overflow so it will become negative in java. For example let's say value of pod_count is -2147483648 and then we pass this value to c++ method and c++ will read this as uint32_t so will it read as negative value or it will read positive number?
All numbers are just a bunch of bits. It's up to the user of those bits to parse them in any way they want. e.g. In C++ if you use 65, which is an integer when you will store it in a char, it will become the letter 'A'. Assume you have 8 bit unsigned int in C++ and a signed 8-bit number in JAVA/C++. The number 1000 1010 will be processed as 138 in unsigned one. But in signed one it will be -118. The key point is the bit-content remains the same. When it overflows, only the 8-bits will be considered no matter what. It could be a -ve or a +ve number depending upon the type.
As long as you are doing only operations on the bits. You are good to go. Otherwise, you might have to move to bigger data types to incorporate sign.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.