Reputation: 354
I am a bit confused by the Oct
function. Oct(-8)
does not return -10, it returns 37777777770. I will just write my own function but does anyone know why it gives such a weird result back?
Upvotes: 4
Views: 386
Reputation: 6738
Throughout the years several ways have been dreamed up for representing negative numbers, but for the sake of keeping this answer on the short side of a dissertation we're only going to look at two's complement.1
To calculate a negative number's two's complement, we use the following steps:
So what's -8 in two's complement binary? First let's convert the absolute value to binary (For now we'll work in 8 bit for simplicity. I've worked out the same answer below with 32 bit numbers.)
|8| => 0000 1000
The next step is to complement all of the bits in the number
0000 1000 => 1111 0111
Finally we add 1 to the result to get our two's complement representation
1111 0111
+ 1
----------
1111 1000 (Don't forget to carry)
Ok, a brief review of octal numbers. Octal, or base 8, is another way of representing binary numbers in a more compact way. The more observant will notice that 8 is a power of 2 and we can certainly use that fact to our advantage converting our negative number to octal.
Oct
produce weird results with negative numbers?The Oct
function operates on the binary representation of the number, converting it to it's octal (Base 8) representation. So let's convert our 8 bit number to octal.
1111 1000 => 11 111 000 => 011 111 000 => 370
Note that since 8 = 2^3
it's easy to convert, because all we have to do is break the number up into groups of three bits and convert each group. (Much like how hex can be converted by breaking into groups of 4 bits.)
Oct
to produce a regular result?Convert the absolute value of the number to octal using Oct
. If the number is less than 0, stick a negative sign in front.
We'll stay with -8 because it's been so good to us this whole time. So converting -8 to two's complement gives:
Convert: 0000 0000 0000 0000 0000 0000 0000 1000
Invert: 1111 1111 1111 1111 1111 1111 1111 0111
Add 1: 1111 1111 1111 1111 1111 1111 1111 1000
Separate: 11 111 111 111 111 111 111 111 111 111 000
Pad: 011 111 111 111 111 111 111 111 111 111 000
Convert: 3 7 7 7 7 7 7 7 7 7 0
Shorten: 37777777770
Which produces the result you're seeing when you call Oct(-8)
.
Armed with this knowledge, you can now also explain why Hex(-8)
produces 0xFFFFFFF8
. (And you can see why I used 8 bit numbers throughout most of this.)
1 For a overly detailed introduction to binary numbers, check out the Wikipedia article
Upvotes: 1