What is the rule for converting a binary value to a negative number and vice versa?

Asked

Viewed 435 times

6

I got a gift after the @Maniero answered that question:

What is the ~ (til) operator for in PHP?

How to obtain the negative value in binary?

And how, through torque, to reach a negative value?

In @Maniero’s reply, he explained that 11111101 is equal to -3.

Because when I do the conversion, it’s returned to me 253.

var_dump(bindec('11111101')); Imprime 253

2 answers

5


Remembering that there I used an example of 8 bits that well spoke the mgibsonbr, is not the way that PHP assembles numbers. This makes all the difference because it will need to do data alignment and will generate a different number than expected because of the signal position.

If you really want to ensure that the first bit of what you send is the signal, as far as I know, you can only do it manually. A documentation have an example:

function bin2si($bin, $bits = 32) { 
    if (strlen($bin) == $bits) { 
        if (substr($bin, 0, 1) == 0) { // positive or zero 
            $si = base_convert($bin, 2, 10); 
        } else { // negative 
            $si = base_convert($bin, 2, 10); 
            $si = -(pow(2, $bits) - $si); 
        } 
        return $si; 
    } 
} 

echo bin2si('11111101', 8);

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • A curiosity: Why the function name is bin2si? What would that be si?

  • 2

    signed integer.

5

Negative numbers - at least for the whole type - are usually represented by complement of two. This means that the most significant digit determines whether the number will be positive or negative. 11111101 is only considered negative if you are working with an 8 bit accuracy (since the 8º bit is 1).

However, an integer in PHP is not only 8 bits, usually 32 bits (but depends on the platform). So, 11111101 actually would be:

00000000 00000000 00000000 11111101

Which is equal to 253. Assuming an accuracy of 32 bits, -3 is equal to:

11111111 11111111 11111111 11111101

As the number of 1s to the left depends on the accuracy, can not do it reliably just increasing the number of 1s (the bindec, incidentally, converts the number to floating point if it is too big to fit an integer). But if you know/specify the accuracy, then the maniero’s response is enough to make this conversion right.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.