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

4

I was left with a doubt after @bigown answered this question:

What is the ~ (useful) operator used in PHP ?

How can I get the negative value in binary?

And how, through the binary, reach a negative value?

In @bigown's response, he explained that 11111101 is equal to -3 .

Because when I do the conversion, I am returned 253 .

var_dump(bindec('11111101')); Imprime 253
    
asked by anonymous 05.08.2015 / 18:35

2 answers

3

Remembering that there I used an example of 8 bits that well said mgibsonbr, is not the way that PHP mounts 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 the send is the signal, as far as I know, you can only do it manually. The documentation has 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);

See working on ideone .

    
05.08.2015 / 18:59
3

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

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

00000000 00000000 00000000 11111101

That is equal to 253 . Assuming a precision of 32 bits, -3 is equal to:

11111111 11111111 11111111 11111101

Since the number of 1 s on the left depends on the precision, you can not do this reliably only by increasing the number of 1 s ( bindec , incidentally, convert the number to floating point if it is too large to fit an integer ). But if you know / specify precision, then the bigown answer method is sufficient to do this formally correct.

    
05.08.2015 / 19:18