Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

2'complement for 8bit variables

19 views
Skip to first unread message

Ron Eggler

unread,
May 24, 2012, 3:29:41 PM5/24/12
to
Hi,

I want to write a a function that takes an 8 bit number and calculates the
2's complement of it and returns a signed character.
What I got so far:
The problem i'm having is, that the multiplication *-1 gives me the wrong
value, assuming i got 20 in num and then make a * -1, I get 236 and I can't
figure out why... anyone?

Thank you!
Ron
Code:

char bintodec(unsigned char bin) {
char num;
num = bin;
printf("0x%x -> 0x%x\n",bin,num);
if (num & 0x80) {
printf("bit 15 set 0x%x!\n",num);
num = ~num;
printf("0x%x\n",num);
num++;
printf("0x%x, %d\n",num,num);
num = num*-1;
printf("%d\n",num);
return num;
}
printf("%d is >=0\n",num);
return 0;
}

--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Jens Thoms Toerring

unread,
May 24, 2012, 3:55:46 PM5/24/12
to
Ron Eggler <ronDOT...@tscheemail.com> wrote:
> I want to write a a function that takes an 8 bit number and calculates the
> 2's complement of it and returns a signed character.
> What I got so far:
> The problem i'm having is, that the multiplication *-1 gives me the wrong
> value, assuming i got 20 in num and then make a * -1, I get 236 and I can't
> figure out why... anyone?

236 (0xEC) is the 2's complement of 20 (0x14). Using the '~' ope-
rator and then adding 1 to the result should work everywhere,
for it to work by multiplying by -1 requires that your machine
uses 2's complement internally (but most do so nowadays, I guess).

> Code:

> char bintodec(unsigned char bin) {
> char num;
> num = bin;
> printf("0x%x -> 0x%x\n",bin,num);
> if (num & 0x80) {
> printf("bit 15 set 0x%x!\n",num);
> num = ~num;
> printf("0x%x\n",num);
> num++;
> printf("0x%x, %d\n",num,num);
> num = num*-1;
> printf("%d\n",num);
> return num;
> }
> printf("%d is >=0\n",num);
> return 0;
> }

From your code it's impossible to say what is going on - for 20 (and
eveything below 127) the function always returns 0. And, if you start
doing bit-diffling you should take care to clearly distinguish between
signed and unsigned variables, e.g. whhy is 'num' a char (which could
be a signed or unsigned, that depends on your architecture) when 'bin'
is an unsigned char? For bit-fiddling it's usually better to stick
to unsigned quantities,
Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

Ron Eggler

unread,
May 24, 2012, 4:06:08 PM5/24/12
to
Jens Thoms Toerring wrote:

> Ron Eggler <ronDOT...@tscheemail.com> wrote:
>> I want to write a a function that takes an 8 bit number and calculates
>> the 2's complement of it and returns a signed character.
>> What I got so far:
>> The problem i'm having is, that the multiplication *-1 gives me the wrong
>> value, assuming i got 20 in num and then make a * -1, I get 236 and I
>> can't figure out why... anyone?
>
> 236 (0xEC) is the 2's complement of 20 (0x14). Using the '~' ope-
> rator and then adding 1 to the result should work everywhere,
> for it to work by multiplying by -1 requires that your machine
> uses 2's complement internally (but most do so nowadays, I guess).

So 0xEC would be -20, right? I'm confdused...
how do I get -20 out of it?? :o
Thanks!
Ron

>
>> Code:
>
>> char bintodec(unsigned char bin) {
>> char num;
>> num = bin;
>> printf("0x%x -> 0x%x\n",bin,num);
>> if (num & 0x80) {
>> printf("bit 15 set 0x%x!\n",num);
>> num = ~num;
>> printf("0x%x\n",num);
>> num++;
>> printf("0x%x, %d\n",num,num);
>> num = num*-1;
>> printf("%d\n",num);
>> return num;
>> }
>> printf("%d is >=0\n",num);
>> return 0;
>> }
>
> From your code it's impossible to say what is going on - for 20 (and
> eveything below 127) the function always returns 0. And, if you start
> doing bit-diffling you should take care to clearly distinguish between
> signed and unsigned variables, e.g. whhy is 'num' a char (which could
> be a signed or unsigned, that depends on your architecture) when 'bin'
> is an unsigned char? For bit-fiddling it's usually better to stick
> to unsigned quantities,
> Regards, Jens


Jens Thoms Toerring

unread,
May 24, 2012, 4:30:36 PM5/24/12
to
Ron Eggler <ronDOT...@tscheemail.com> wrote:
> Jens Thoms Toerring wrote:

> > Ron Eggler <ronDOT...@tscheemail.com> wrote:
> >> I want to write a a function that takes an 8 bit number and calculates
> >> the 2's complement of it and returns a signed character.
> >> What I got so far:
> >> The problem i'm having is, that the multiplication *-1 gives me the wrong
> >> value, assuming i got 20 in num and then make a * -1, I get 236 and I
> >> can't figure out why... anyone?
> >
> > 236 (0xEC) is the 2's complement of 20 (0x14). Using the '~' ope-
> > rator and then adding 1 to the result should work everywhere,
> > for it to work by multiplying by -1 requires that your machine
> > uses 2's complement internally (but most do so nowadays, I guess).

> So 0xEC would be -20, right? I'm confdused...
> how do I get -20 out of it?? :o

0xEC would be -20 if it is interpreted as a signed int.
Question is how you intent to print it out. Here's some
way it should work

#include <stdio.h>

char bintodec( unsigned char in ) {
return ~in + 1;
}

int main( void ) {
printf( "%d\n", ( signed char ) bintodec( 20 ) );
return 0;
}

The cast to signed char in the printf() call may be superfluous
on your system if a char is signed by default but on those were
char is unsigned it makes all the difference;-) And then, accor-
ding to the C rules for promotions the signed char is (silenty)
converted to an int and that is printed. Of course, on a machine
that doesn't use 2's complement the output wouldn't be -20 since
then using '~' and adding 1 doesn't "negate" the value, one a
1's complement machine you would have to drop adding 1 to get
the negative of the input value...

jgharston

unread,
May 24, 2012, 5:05:31 PM5/24/12
to
Ron Eggler wrote:
> So 0xEC would be -20, right? I'm confdused...
> how do I get -20 out of it?? :o

EC -20
ED -19
EE -18
EF -17
F0 -16
F1 -15
F2 -14
F3 -13
F4 -12
F5 -11
F6 -10
F7 -9
F8 -8
F9 -7
FA -6
FB -5
FC -4
FD -3
FE -2
FF -1

JGH

Wayne C. Morris

unread,
May 24, 2012, 5:19:14 PM5/24/12
to
In article <jpm4bt$1d0b$4...@adenine.netfront.net>,
Ron Eggler <ronDOT...@tscheemail.com> wrote:

> Jens Thoms Toerring wrote:
>
> > Ron Eggler <ronDOT...@tscheemail.com> wrote:
> >> I want to write a a function that takes an 8 bit number and calculates
> >> the 2's complement of it and returns a signed character.
> >> What I got so far:
> >> The problem i'm having is, that the multiplication *-1 gives me the wrong
> >> value, assuming i got 20 in num and then make a * -1, I get 236 and I
> >> can't figure out why... anyone?
> >
> > 236 (0xEC) is the 2's complement of 20 (0x14). Using the '~' ope-
> > rator and then adding 1 to the result should work everywhere,
> > for it to work by multiplying by -1 requires that your machine
> > uses 2's complement internally (but most do so nowadays, I guess).
>
> So 0xEC would be -20, right? I'm confdused...
> how do I get -20 out of it?? :o
> Thanks!
> Ron

char can be either signed or unsigned; it's implementation-defined. Your
compiler treats char as unsigned, so ((char) 0xEC) is 236. If you want signed
characters, you have to use signed char instead of char.

Ike Naar

unread,
May 24, 2012, 6:02:18 PM5/24/12
to
On 2012-05-24, Ron Eggler <ronDOT...@tscheemail.com> wrote:
> char bintodec(unsigned char bin) {
> char num;

If you want signed char, use signed char, not char.
Plain char can be either signed or unsigned, depending on
the implementation you're using.

> num = bin;
> printf("0x%x -> 0x%x\n",bin,num);
> if (num & 0x80) {
> printf("bit 15 set 0x%x!\n",num);

Bit 15 or bit 7 ?

> num = ~num;
> printf("0x%x\n",num);
> num++;
> printf("0x%x, %d\n",num,num);
> num = num*-1;
> printf("%d\n",num);
> return num;
> }
> printf("%d is >=0\n",num);
> return 0;

Why 0 ?

> }
0 new messages