I sent this about a week ago, but I forgot to 'reply to all', and send
it to the list.
Thanks Rolf for pointing that out to me.

I'm not totally sure, but this might work. I'm too tired to understand
rolf's masks, but:

<?php

function bin2int($bin){
  $a = bindec($bin);
  return ($a < 128) ? ($a) : ($a - 256);
} Not sure if that's faster or not.

You could also try using string indices, instead of substr.

function bin2int($bin){
  if(  $bin{0} ){
    return bindec($bin) - 256;
  } else {
    return bindec($bin);
}

or using ? :

function bin2int($bin){
  return ($bin{0}) ? (bindec($bin) - 256) : bindec($bin);
}

It's not something I'd worry about too much, although I would advocate
getting rid of your substr()'s
On 26 Apr 2005 19:40:10 -0000, Rolf Řstvik <[EMAIL PROTECTED]> wrote:
> [EMAIL PROTECTED] (René Fournier) wrote in
> news:[EMAIL PROTECTED]:
>
> > I need to convert a binary number of arbitrary length to a signed
> > integer.
> > This is how I'm doing it now:
> > CODE
> > --------
> > function bin2int ($bin) {
> >      if (substr($bin,0,1) == 1) {
> >           $val = 0 - bindec(substr($bin,1));     // NEGATIVE
> >           } else {
> >           $val = bindec(substr($bin,1));     // POSITIVE
> >           }
> >      }
> >
> > echo bin2int("00001101").'<br />';
> > echo bin2int("10001101");
> >
> > OUTPUT
> > --------
> > 13
> > -13
> >
> > As you can see, if the most-significant bit is 1, then the rest of the
> > value is negative. If the first bit is 0, then the rest is positive.
>
> If this is what you want then your numeric representation of negative
> numbers is not standard. In that case your function is as good as you can
> get.
>
> This is the standard two's complement representation:
> "00001101"      is 13
> "11110010"      is -13
> "10001101"      is -115
>
> You specify the most-significant bit as sign bit, and that you can have a
> arbitrary lenght string representing a binary number.
> Then "010" will be different than "10", is that correct?
>
> If you on the other hand know that the string should represent an 8 bit in
> two's complement then this could work:
>
> function bin2int ($bin) {
>     $a =  bindec($bin);
>
>     $val = ($a | 0x80) ? (0xffffff00 | $a) : $a;
>
>     return $val;
> }
>
> //  or by using if instead of ? and :
> //function bin2int ($bin) {
> //    $a =  bindec($bin);
> //  if ( $a | 0x80) {
> //      $val = (0xffffff00 | $a);
> //  } else {
> //      $val =$a;
> //  }
> //
> //    return $val;
> //}
>
> If the string represent a 16 bit number use
> $val = ($ | 0x8000) ? (0xffff0000 | $a) : $a;
>
> If the string represent a 32 bit number use only bindec
>
> If you still want
>  - a leading 1 to represent a negative number,
>  - and that the string can have arbitrary lenght,
>  - but you want correct two's complement representation
> then we need something different, e.g:
>
> function bin2int ($bin) {
>     if (substr($bin,0,1) == 1) {
>         // NEGATIVE
>         $val = bindec(substr("11111111111111111111111111111111".$bin,-32));
>     } else {
>            // POSITIVE
>         $val = bindec($bin);
>     }
>     return $val;
> }
>
> --
> Rolf
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to