Two's compliment [SOLVED]

General FreeBASIC programming questions.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Two's compliment [SOLVED]

Post by Dinosaur »

Hi all

Is there a simpler way to converting a Two's compliment number to Integer
without doing the bit crunching ?

Regards
Last edited by Dinosaur on Feb 21, 2023 6:28, edited 1 time in total.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Two's compliment

Post by fxm »

???

When applied to an integer number, the two's complement of a number corresponds to the 'negate' operation and vice versa.

Example on an integer:

Code: Select all

Dim As Integer I = 5
Dim As Integer J = -I
Dim As Integer K = -J

Print Bin(I)
Print Bin(J)
Print Bin(K)

Sleep
for the 32-bit fbc version

Code: Select all

101
11111111111111111111111111111011
101

The (one's) complement corresponds to the 'Not' operator.
The two's complement corresponds to the 'Not' operator + 1, that is to say the operator '- (Negate)'.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Two's compliment

Post by coderJeff »

Also for me, ???. Maybe 'Integer' in the mathematical sense? like 0, 1, 2, 3 ...
As mentioned (by fxm), two's compliment is a way to represent negative numbers, so negation will get back the non-negative number.

Code: Select all

print "i", "bin(i)", "negative", "number", "bin(number)"
for i as byte = -100 to 100 step 25
	dim negative as boolean = ( i < 0 )
	dim number as byte = iif( i < 0, -i, i )
	print i, bin(i,8), negative, number, bin(number, 8)
next

/' OUTPUT:
i             bin(i)        negative      number        bin(number)
-100          10011100      true           100          01100100
-75           10110101      true           75           01001011
-50           11001110      true           50           00110010
-25           11100111      true           25           00011001
 0            00000000      false          0            00000000
 25           00011001      false          25           00011001
 50           00110010      false          50           00110010
 75           01001011      false          75           01001011
 100          01100100      false          100          01100100
'/
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Two's compliment

Post by caseih »

I'm a bit confused. A number in two's compliment *is* an integer by definition. That's the whole idea.

Are you really asking if there's a way to find the absolute value of the signed integer without bit twiddling? The answer to that is no; it always requires a negation operation, which is really a two-step process: invert all the bits and add one. But CPUs can do it in one instruction.

The only special consideration needed when working with two's complement numbers is that when you want to convert a number to a different word size you must do sign extension, and when shifting right you must shift in a sign bit in the MSB which CPUs all that natively. Thus in FB you can just cast values to whatever type size you want.

Quite an ingenious scheme, two's complement. No special adder circuitry required to make it work. Kind of funny that the early Cray super computers operated on 1's complement, and thus had to have special circuitry to deal with signed numbers. Mr Cray was asked why he did that and he said it was because he didn't know about 2's complement notation at the time. Would have saved him a lot of time and expense.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Two's compliment

Post by dodicat »

There is little benefit speed wise with negate the standard way and negate by using not.

Code: Select all

#define negate(n) not(n)-1

for n as long=1 to 20
      var k=int(rnd*500000000-rnd*500000000)
      print k,bin(k,64)
      print negate(k),bin(negate(k),64)
      print
next


randomize 1

dim as longint k,m
dim as double t=timer

for n as long=1 to 1000000
       k =(rnd*500000000-rnd*500000000)
       m=negate(k)
next
print timer-t,k,m


randomize 1
t=timer
for n as long=1 to 1000000
       k =(rnd*500000000-rnd*500000000)
       m=-k
next
print timer-t,k,m

sleep
 
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Two's compliment

Post by caseih »

To be clear you always add 1 after the NOT operation, regardless of which way you are going.
Last edited by caseih on Feb 20, 2023 19:31, edited 2 times in total.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Two's compliment

Post by fxm »

@dodicat,

Your 'negate' macro is twisted ( not educational at all ), because:
not(n)-1
is parsed as:
not n - 1
which is equivalent to:
not (n - 1)
due to the two operators precedence ('not' and '-').

I prefer the true definition with better syntax ('Not' is an unary operator, not a function):
#define negate(n) ((not (n)) + 1)
Last edited by fxm on Feb 21, 2023 15:11, edited 3 times in total.
Reason: To remove the "twisted" term and add prentheses around 'n' in my macro version.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Two's compliment

Post by Dinosaur »

Hi All
Many thanks for the replies.

I knew when I wrote the word Integer, I would get in trouble.
Sure enough, but correctly so.

I am getting a 16 bit number that is in Two's compliment format from an A2d converter.
So, my true resolution is 15 bits with bit 16 the sign.

An example:

Code: Select all

#define negate(n) ((not n) + 1)
Dim as Integer n
n = &h63AF
Print Bin(&H63AF)
n = negate(n)
Print Bin(n)
This produces what looks like a 32 bit number.

Code: Select all

110001110101111
1111111111111111111111111111111111111111111111111001110001010001
Regards

Edit
Dim n as Short produces
110001110101111 which only has the leading zero missing
1001110001010001
Last edited by Dinosaur on Feb 20, 2023 21:14, edited 2 times in total.
hhr
Posts: 206
Joined: Nov 29, 2019 10:41

Re: Two's compliment

Post by hhr »

I tried this and found that dealing with 'Not' is not easy.
The documentation says 'result = Not rhs'. If I pay attention to rhs, I can understand that.

My question: Why does dodicat's program work?

Code: Select all

dim as byte i,j,k
i=121
print i,"This is i"
print not(i) + 1 , "This is not -i"
print not i + 1 , "This is not -i"
print not(i + 1) , "This is not -i"
print (not i) + 1

print

j=(not i)+1
print j,bin(j,8*len(i))
k=not(j-1)
print k,bin(k,8*len(i))

sleep
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Two's compliment

Post by fxm »

@Dinosaur,

I still do not understand what you are trying to do, but:

Code: Select all

Dim as Short n
n = &h63AF
Print Bin(&H63AF, 8 * Len(Short))
n = -n
Print Bin(n, 8 * Len(Short))

Calling the 'Not' operator with 'Not(x)' instead of 'Not x' is a bad and misleading habit, because 'Not' is an unary operator and not a function.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Two's compliment

Post by Dinosaur »

Hi All

Rushing this, need to sit back.

If the number is Two's compliment, BUT bit 16 is zero then there is no need for conversion.
As my example above shows.
So, I have to check for this.

Regards
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Two's compliment

Post by fxm »

Not fully understand your problem yet.
The 'negate' macro is nothing but the '-' operator.

Dinosaur wrote: Feb 20, 2023 21:19 If the number is Two's compliment, BUT bit 16 is zero then there is no need for conversion.
Perhaps what you are looking for is simply the 'Abs' function ?

Code: Select all

Dim As Short n0
n0 = &h63AF
Dim As Short n

Print Bin(n0, 8 * Len(Short))
n = Abs(n0)
Print Bin(n, 8 * Len(Short))
Print
Print Bin(-n0, 8 * Len(Short))
n = Abs(-n0)
Print Bin(n, 8 * Len(Short))
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Two's compliment

Post by Dinosaur »

Hi All
I am getting a 16 bit number that is in Two's compliment format from an A2d converter.
So, my true resolution is 15 bits with bit 16 the sign.
I need to convert negative numbers to positive.
But with the examples above where does the + 1 come in ?
If we simply flip the bits , then I can do:

Code: Select all

If Bit(n,16) Then n = -n	'Otherwise do nothing
If I use Hex 88F0 as an example.
The resultant number is -30480, then after the conversion it is +30480.
Should that be +30481 ?

Regards
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Two's compliment

Post by dodicat »

fxm wrote: Feb 20, 2023 19:28 @dodicat,

Your 'negate' macro is twisted (not educational at all), because:
not(n)-1
is parsed as:
not n - 1
which is equivalent to:
not (n - 1)
due to the two operators precedence ('not' and '-').

I prefer the true definition with better syntax ('Not' is an unary operator, not a function):
#define negate(n) ((not n) + 1)
not n-1 suits a negation for +ve and -ve numbers.
And I bracket off the n to not (n)-1, to handle compound expressions, which is usual in a macro.
I don't know why you think it is twisted.
There is no obvious reason why a + operator must be used.
If you prefer to incorporate a + then fair enough, but "twisted and not educational at all" is not required here.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Two's compliment

Post by fxm »

Dinosaur wrote: Feb 20, 2023 22:17 But with the examples above where does the + 1 come in ?
Because
-n
is equivalent to
(Not n) + 1
Post Reply