1

I have cracked my head enough and hence asking here:

This works:

int dummy_1, dummy_2; long final_dummy; dummy_1 = 0x12345678; dummy_2 = 0x78563412; final_dummy = (long)dummy_1 | (long)dummy_2<<32; System.out.println(String.format("%08X", final_dummy)); 

Answer : 7856341212345678

This doesnt work:

int dummy_1, dummy_2; long final_dummy; dummy_1 = 0xB6F93000; dummy_2 = 0xB6F93000; final_dummy = (long)dummy_1 | (long)dummy_2<<32; System.out.println(String.format("%08X", final_dummy)); 

Answer: FFFFFFFFB6F93000

Expected answer : B6F93000B6F93000

2
  • 1
    Hint: print out dummy_1 and dummy_2 first. They're not the values you think they are. Look at the range of int. Also, your code would be easier to read if you followed Java naming conventions, and declared your variables at the point of first use. Commented Nov 17, 2015 at 18:17
  • what is your question? Commented Nov 17, 2015 at 18:17

2 Answers 2

3

0xB6F93000 is actually the int value -1225183232. When coerced to long, it becomes 0xFFFFFFFFB6F93000L, which is also -1225183232.

When you convert int to long you need to make it an unsigned conversion.

// In Java 8 int dummy_1 = 0xB6F93000; int dummy_2 = 0xB6F93000; long final_dummy = Integer.toUnsignedLong(dummy_1) | Integer.toUnsignedLong(dummy_2) << 32; // In all Java versions int dummy_1 = 0xB6F93000; int dummy_2 = 0xB6F93000; long final_dummy = (dummy_1 & 0xFFFFFFFFL) | (long)dummy_2 << 32; 
Sign up to request clarification or add additional context in comments.

Comments

1

In the code that doesn't work, your initial dummy_1 and dummy_2 values are negative; in Java, all numeric types are signed. The highest bit is set, which is seen because the first hex digit is greater than or equal to 8.

Because these values are negative, when casted to a long, sign extension occurs.

0xB6F93000 => 0xFFFFFFFFB6F9000L 

When logically ORed, those F digits remain, explaining why the most significant 8 hex digits (4 bytes) are Fs instead of your value.

Use a mask to clear those sign-extended bits prior to ORing them.

final_dummy = (((long) dummy_1) & 0xFFFFFFFFL) | (((long)dummy_2) & 0xFFFFFFFFL) << 32; 

This will clear the most significant 8 hex digits, as if sign extension did not take place. With this change, I get:

B6F93000B6F93000 

Bit-anding on dummy_2 is not necessary, because the shift eliminates those 32 bits anyway.

final_dummy = (((long) dummy_1) & 0xFFFFFFFFL) | (long) dummy_2 << 32; 

As an aside, normal Java naming conventions dictate that the variables names should be dummy1, dummy2, and finalDummy.

1 Comment

Also no need to cast dummy_1 to long, since int & long will coerce the int to long implicitly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.