How to combine 2 unsigned short into a unsigned int?

F

fancyerii

Hi, everyone.
The question is: I have 2 unsigned short, And I want to "concat"
this 2 short into a unsigned ingeger value.
If in C, it may be implemented like :
unsigned short s1; //s1 ranges from 0 to 65535
unsigned short s2;
unsigned int=(s1<<16)+s2;

But there is no unsigned in java, All integers are signed. So how
can I achieved my goal in java ? (s1 may be very large, say
40,000>32767)
Thanks!
 
I

instcode

Hi, everyone.
The question is: I have 2 unsigned short, And I want to "concat"
this 2 short into a unsigned ingeger value.
If in C, it may be implemented like :
unsigned short s1; //s1 ranges from 0 to 65535
unsigned short s2;
unsigned int=(s1<<16)+s2;

But there is no unsigned in java, All integers are signed. So how
can I achieved my goal in java ? (s1 may be very large, say
40,000>32767)
Thanks!

As in JVM spec, int-type uses 4 bytes to store a signed integer on
every JVM.

int s1;
int s2;

Because s1, s2 values fall into an unsigned-short (2 bytes) range, its
*meaning-value* is only stored in *2 lowest bytes* of a Java-integer.
Understanding binary/hexa form of a number, we can "concat" these
numbers as following:

int s3 = ((s1 & 0xFFFF) << 16) | (s2 & 0xFFFF);

Hope this helps.
 
F

fancyerii

As in JVM spec, int-type uses 4 bytes to store a signed integer on
every JVM.

int s1;
int s2;

Because s1, s2 values fall into an unsigned-short (2 bytes) range, its
*meaning-value* is only stored in *2 lowest bytes* of a Java-integer.
Understanding binary/hexa form of a number, we can "concat" these
numbers as following:

int s3 = ((s1 & 0xFFFF) << 16) | (s2 & 0xFFFF);

Hope this helps.

Thanks.
 
R

rossum

As in JVM spec, int-type uses 4 bytes to store a signed integer on
every JVM.

int s1;
int s2;

Because s1, s2 values fall into an unsigned-short (2 bytes) range, its
*meaning-value* is only stored in *2 lowest bytes* of a Java-integer.
Understanding binary/hexa form of a number, we can "concat" these
numbers as following:

int s3 = ((s1 & 0xFFFF) << 16) | (s2 & 0xFFFF);

The problem you might get is that if the high bit of s3 is set then
the result will be treated as negative.

Just as you used a signed int to hold an unsigned short, you should
use a signed long (8 bytes) to hold an unsigned 4 byte int, so s3
should be a long.

rossum
 
F

fancyerii

But when I run these codes, It's not the result I want.
int i1=24785;
int i2=42113;
int rt;
rt=(i1&0xFFFF)<<16+(i2&0xffff);
The answer I got is : -1046347776 it's a negative.
While in c the result is 1624351873.
What's wrong?

instcode
 
L

Lew

fancyerii said:
But when I run these codes, It's not the result I want.
int i1=24785;
int i2=42113;
int rt;
rt=(i1&0xFFFF)<<16+(i2&0xffff);
The answer I got is : -1046347776 it's a negative.
While in c the result is 1624351873.
What's wrong?

First, that you top-posted. Please use trim-and-inline posting.

Did you read rossum's message? Let me quote it:
The problem you might get is that if the high bit of s3 is set then
the result will be treated as negative.

Just as you used a signed int to hold an unsigned short, you should
use a signed long (8 bytes) to hold an unsigned 4 byte int, so s3
should be a long.

You know that Java doesn't have unsigned integer types, so why do you ask
what's wrong? What you call "wrong" is just that Java doesn't have unsigned
integer types.
 
L

Lew

fancyerii said:
I replace int s3 by long s3, but it still got a negative .

Please do not top-post. Use trim-and-inline posting.

See all that masking going on to make a short look unsigned as an int?

Envision all that masking going on to make an int look unsigned as a long.

It sounds like you need to read up on:
<http://java.sun.com/docs/books/tutorial/index.html>
particularly
<http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html>
and
<http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html>
 
P

Patricia Shanahan

fancyerii said:
But when I run these codes, It's not the result I want.
int i1=24785;
int i2=42113;
int rt;
rt=(i1&0xFFFF)<<16+(i2&0xffff);
The answer I got is : -1046347776 it's a negative.
While in c the result is 1624351873.
What's wrong?

A couple of things. First of all, you are missing some parentheses:

rt=((i1&0xFFFF)<<16)+(i2&0xffff);

Although it is not necessary in this case, because the leading bit of i1
is zero, in general you need to print it as the low order 32 bits of a
long to avoid negative output:

System.out.println(rt & 0xffffffffL);

May I ask why you are doing all this? Generally, a short[2] is a more
convenient, less fiddly, representation of a pair of short values.

Patricia
 
F

fancyerii

Lew
First, that you top-posted. Please use trim-and-inline posting.

Did you read rossum's message? Let me quote it:

You know that Java doesn't have unsigned integer types, so why do you ask
what's wrong? What you call "wrong" is just that Java doesn't have unsigned
integer types.

Sorry, I'm not familiar with the google group.
 
F

fancyerii

Patricia Shanahan
fancyerii said:
But when I run these codes, It's not the result I want.
int i1=24785;
int i2=42113;
int rt;
rt=(i1&0xFFFF)<<16+(i2&0xffff);
The answer I got is : -1046347776 it's a negative.
While in c the result is 1624351873.
What's wrong?

A couple of things. First of all, you are missing some parentheses:

rt=((i1&0xFFFF)<<16)+(i2&0xffff);

Although it is not necessary in this case, because the leading bit of i1
is zero, in general you need to print it as the low order 32 bits of a
long to avoid negative output:

System.out.println(rt & 0xffffffffL);

May I ask why you are doing all this? Generally, a short[2] is a more
convenient, less fiddly, representation of a pair of short values.

Patricia

I want to mapping bigram(2 words sequence) into a number.
I have a dictionary whose size is about 50,000. So I give each word a
number.
And for a bigram <w1,w2>, I want to mapping it into a number.
So I want to use w1 as the higher 16 bits and w2 as the lower 16 bits.
 
R

rossum

[Top posting modified.]
But when I run these codes, It's not the result I want.
int i1=24785;
int i2=42113;
int rt;
You should declare rt as a long, not an int. As an int rt will only
hold 31 unsigned bits, not 32. A long will hold up to 63 unsigned
bits.
rt=(i1&0xFFFF)<<16+(i2&0xffff);
As Patricia has pointed out you are missing a pair of brackets:

rt = ((i1 & 0xFFFF) << 16) + (i2 & 0xffff);
^ ^
I would also be inclined to make at least one of the operands a long,
just to be sure that the addition is done in 64 bits, not 32:

result = ((i1 & 0xFFFF) << 16) + (long)(i2 & 0xFFFF);
The answer I got is : -1046347776 it's a negative.
While in c the result is 1624351873.
What's wrong?
Look at the bit pattern used to represent both numbers. Pay especial
attention to the most significant bit of the pattern. Now look up
what role the most significant bit plays in a 32 bit Java integer.

rossum
 
P

Patricia Shanahan

rossum wrote:
....
I would also be inclined to make at least one of the operands a long,
just to be sure that the addition is done in 64 bits, not 32:

result = ((i1 & 0xFFFF) << 16) + (long)(i2 & 0xFFFF);

It is fine to the addition in 32 bits. No need to make the calculation
long. The result will be the same as the low order 32 bits that would
have resulted if it had been done as long.

The differences between unsigned and 2's complement signed lie in other
areas, such as comparison and conversion results.

Patricia
 
P

Patricia Shanahan

fancyerii wrote:
....
I want to mapping bigram(2 words sequence) into a number.
I have a dictionary whose size is about 50,000. So I give each word a
number.
And for a bigram <w1,w2>, I want to mapping it into a number.

I assume you have too many bigrams to spare an extra 4 bytes each to use
a pair of references, instead of the int? Beware of using long to get
unsignedness - it will cost you the space you are saving by not using
references.
So I want to use w1 as the higher 16 bits and w2 as the lower 16 bits.

Why do the numbers have to be unsigned?

Patricia
 
R

Roedy Green

The answer I got is : -1046347776 it's a negative.
While in c the result is 1624351873.
What's wrong?

Java does not support unsigned. You used a signed printing routine.
To see it as C does, you would have to use an unsigned printing
routine. The bits are the same for both. You would have to write your
own unsignedToString method. You would write a very simple one by
masking off the high 32 bits after a conversion to long, then a
Long.toString.

see http://mindprod.com/jgloss/unsigned.html
for the code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top