Help! How to program about 2's complemet with 22 bits value?

C

cylin

Hi all,

If I have a variable and it's just have 22 bits,
and I must set this variable unsigned integer.
This 2's complement value maybe is negative.

For example:
A= 11 1111 1111 1110 1100 0000 = 4193984
3 f f e c 0
A's 2's complement should be
00 0000 0000 0001 0100 0000 = 320

I try to write a sample code below:
----------------------------------------------------
unsigned int A=4193984;
unsigned char Byte2=~(((A & 0x00ff0000) >> 16)+192); // 192 is sum of
the first 2 bits of one byte.
unsigned char Byte3=~((A & 0x0000ff00) >> 8);
unsigned char Byte4=~(A & 0x000000ff);
unsigned int ATwoSComplement=(Byte2 << 16) + (Byte3 << 8) + Byte4 + 1;
----------------------------------------------------
But when some variable's 2's complement is negative, this code fails.
How to find it's 2's complement value correctly?
Thanks for your help.

Regards,
cylin.
 
K

Karl Heinz Buchegger

cylin said:
Hi all,

If I have a variable and it's just have 22 bits,
and I must set this variable unsigned integer.
This 2's complement value maybe is negative.

For example:
A= 11 1111 1111 1110 1100 0000 = 4193984
3 f f e c 0
A's 2's complement should be
00 0000 0000 0001 0100 0000 = 320

I try to write a sample code below:
----------------------------------------------------
unsigned int A=4193984;
unsigned char Byte2=~(((A & 0x00ff0000) >> 16)+192); // 192 is sum of
the first 2 bits of one byte.
unsigned char Byte3=~((A & 0x0000ff00) >> 8);
unsigned char Byte4=~(A & 0x000000ff);
unsigned int ATwoSComplement=(Byte2 << 16) + (Byte3 << 8) + Byte4 + 1;

What you have looks too complicated. Also: I don't
understand what the addition of 192 should account for.

Can I assume that sizeof( unsigned int ) >= 4 ?
What's wrong with:

unsigned int ATwoSComplement = ( ~A + 1 ) & 0x003FFFFF;
 
C

cylin

"cylin" <[email protected]> ¼¶¼g©ó¶l¥ó·s»D
:[email protected]...
Hi all,

If I have a variable and it's just have 22 bits,
and I must set this variable unsigned integer.
This 2's complement value maybe is negative.

For example:
A= 11 1111 1111 1110 1100 0000 = 4193984
3 f f e c 0
A's 2's complement should be
00 0000 0000 0001 0100 0000 = 320

I try to write a sample code below:
----------------------------------------------------
unsigned int A=4193984;
// 192 is sum of the first 2 bits of one byte.
unsigned char Byte2=~(((A & 0x00ff0000) >> 16)+192);
unsigned char Byte3=~((A & 0x0000ff00) >> 8);
unsigned char Byte4=~(A & 0x000000ff);
// ATwoSComplement should be long integer,not unsigned integer
long ATwoSComplement=(Byte2 << 16) + (Byte3 << 8) + Byte4 + 1;
----------------------------------------------------
But when some variable's 2's complement is negative, this code fails.
How to find it's 2's complement value correctly?
Thanks for your help.

Regards,
cylin.
 
C

cylin

unsigned int ATwoSComplement = ( ~A + 1 ) & 0x003FFFFF;

Yes, that's simple.
But it seems that "( ~A + 1 ) & 0x003FFFFF" is always positive.
How can I handle if the 2's complement is negative?
Thanks.

Regards,
cylin.
 
K

Karl Heinz Buchegger

cylin said:
unsigned int ATwoSComplement = ( ~A + 1 ) & 0x003FFFFF;

Yes, that's simple.
But it seems that "( ~A + 1 ) & 0x003FFFFF" is always positive.
How can I handle if the 2's complement is negative?

It is bit 21 which tells you if the number should be output
as a negative one.

bit 21 set -> negative number. output '-' and the 2-s complement of the number
bit 21 not set -> positive number, just output it.

So in your case:

22 1111 1111 1100 0000 0000
10 9876 5432 1098 7654 3210

A= 11 1111 1111 1110 1100 0000 = 4193984

since bit 21 is set, A holds a negative number.
But which one:

11 1111 1111 1110 1100 0000 number
00 0000 0000 0001 0011 1111 1-compl
00 0000 0000 0001 0100 0000 2-compl = 256 + 64 = 320

so the bit pattern

11 1111 1111 1110 1100 0000

represents the number -320

The benefit of 2-s complement comes into play when doing
arithmetic. You just don't care if the number is positive
or negativ, you simply treat all numbers as beeing positive
and do the arithmetic (the sign bit will take care of itself).

It is only during input/output that an entered sign or bit 21 needs
attention.
Input: If the user enters a negative number, you read that
number as if it were a positive one (without the '-') and
do a 2-s complement on it to negate it.

Output: if bit 21 is set, you output a '-' since it is a negative
number, apply 2-s complement on the number (again: to negate it
and thus make it positive) and output that number.

Also note: with 22 bits, one bit for sign, you can't
represent 4193984. You simply don't have enough bits
for it.

Also note: you can't use your compilers facilities to output
negative numbers, since your compiler doesn't know that you
treat bit 21 as the sign bit. Thats why it is not meaningfull
in your case to talk about the number 4193984 although you
will see that number when you do a printf on A. But your
compiler doesn't know that bit 21 is the sign bit, thus ...

void OutputMyNumber( unsigned int A )
{
if( A & 0x002000000000 ) { // bit 21 set?
// if yes: negative number
printf( "-" );
A = ( ~A + 1 ) & 0x003FFFFF;
}
printf( "%d", A );
}
 
K

Karl Heinz Buchegger

Karl said:
It is bit 21 which tells you if the number should be output
as a negative one.

bit 21 set -> negative number. output '-' and the 2-s complement of the number
bit 21 not set -> positive number, just output it.

So in your case:

22 1111 1111 1100 0000 0000
10 9876 5432 1098 7654 3210

A= 11 1111 1111 1110 1100 0000 = 4193984

since bit 21 is set, A holds a negative number.
But which one:

11 1111 1111 1110 1100 0000 number
00 0000 0000 0001 0011 1111 1-compl
00 0000 0000 0001 0100 0000 2-compl = 256 + 64 = 320

so the bit pattern

11 1111 1111 1110 1100 0000

represents the number -320

The benefit of 2-s complement comes into play when doing
arithmetic. You just don't care if the number is positive
or negativ, you simply treat all numbers as beeing positive
and do the arithmetic (the sign bit will take care of itself).

It is only during input/output that an entered sign or bit 21 needs
attention.
Input: If the user enters a negative number, you read that
number as if it were a positive one (without the '-') and
do a 2-s complement on it to negate it.

Output: if bit 21 is set, you output a '-' since it is a negative
number, apply 2-s complement on the number (again: to negate it
and thus make it positive) and output that number.

Also note: with 22 bits, one bit for sign, you can't
represent 4193984. You simply don't have enough bits
for it.

Also note: you can't use your compilers facilities to output
negative numbers, since your compiler doesn't know that you
treat bit 21 as the sign bit. Thats why it is not meaningfull
in your case to talk about the number 4193984 although you
will see that number when you do a printf on A. But your
compiler doesn't know that bit 21 is the sign bit, thus ...

void OutputMyNumber( unsigned int A )
{
if( A & 0x002000000000 ) { // bit 21 set?
// if yes: negative number
printf( "-" );
A = ( ~A + 1 ) & 0x003FFFFF;


Sorry: must be .... & 0x001FFFFF;
since we want to get rid of the sign bit also.
 
C

cylin

Dear Karl,

Regard to your method,
I solve it.
Thanks you very much.

Best Regards,
cylin.
 

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,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top