Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > операцию ^ совместить с JavaScript


Автор: admsasha 21.5.2007, 18:04
в JavaScript есть такой код

6537379050^1797494240, резутат -292829726

если пишу тоже самое на perl, то результат 2497473055


Что это (^) за действие ? 
Почему результаты разные, и как их сделать одинаковыми, что в Perl поправить ?


P.s. ой, не туда вопрос, промазал... модеры прошу перенести... как я понимаю, это должно быть в системном...

Автор: admsasha 22.5.2007, 15:41
Вообщем надо вот эту функцию переписать, может у кого идеи есть....

Код

function foo(word1,word2) {
    var rez=word1^word2;
    var max32=0xffffffff;
    if ( rez < 0 ) rez = max32 + 1 + rez;
    return rez; 
} 


Автор: Ivan Kolesnikov 24.5.2007, 14:58
Твой пост меня заинтересовал... решил разобраться.

Операция которую ты здесь привел - это побитовый xor

Теперь почему разные результаты.

Правильный результат:

Код

  6537379050^1797494240 = 8297113866


Как видно результат больше 2^32 и Javascript приводит его к 32 разрядам

Код

8297113866 - 2*2^32 = -292820726 (у тебя -292829726, я думаю это описка)


Теперь о Perl. Он делает совсем хитро, так как 1-е число не помещается в 32 разряда, он заменяет его максимальным 32 разрядным беззнаковым, то есть 2^32-1 = 4294967295

Получается
Код

4294967295^1797494240 = 2497473055


Автор: admsasha 24.5.2007, 15:15
А идеи есть как javascript код, написать на perl ? (JavaScript код подогнать под perl вроде как получиться, а вот наоборот :-( )

т.е. результаты должны быть одинаковы... но Javascipt код менять нельзя.

Автор: Ivan Kolesnikov 25.5.2007, 07:42
Вот что я придумал
Код

use warnings;
use strict;

foo(6537379050,1797494240);

sub to_int32 {
  my $v = shift;
  my $c = 0xFFFFFFFF;
  $v-=2*$c while $v>=$c;
  $v+=2*$c while $v<-$c;
  return $v;
};

sub foo {
  my ($word1, $word2) = @_;
  my $r = to_int32(to_int32($word1) ^ to_int32($word2));
  $r = 0xFFFFFFFF + 1 + $r if $r<0;
  return $r;
} 


Оно не совсем в стиле Perl (можно наверное покороче), но на приведенных тобой парах работает, на других не знаю не проверял...

Автор: admsasha 25.5.2007, 12:41
Цитата(Ivan Kolesnikov @  25.5.2007,  14:42 Найти цитируемый пост)
Оно не совсем в стиле Perl (можно наверное покороче), но на приведенных тобой парах работает, на других не знаю не проверял... 

Результат  4002146572, а надо -292820726, так что не подходит  smile 

Автор: Ivan Kolesnikov 25.5.2007, 13:03
Сори... чуть-чуть ошибся

Код

use warnings;
use strict;

print foo1(6537379050,1797494240);
print "\n";
print foo2(6537379050,1797494240);

sub to_int32 {
  my $v = shift;
  my $c = 0x80000000;
  $v-=2*$c while $v>=$c;
  $v+=2*$c while $v<-$c;
  return $v;
};

sub foo1 {
  my ($word1, $word2) = @_;
  my $r = to_int32(to_int32($word1) ^ to_int32($word2));
  $r = 0xFFFFFFFF + 1 + $r if $r<0;
  return $r;
}

sub foo2 {
  my ($word1, $word2) = @_;
  my $r = to_int32($word1) ^ to_int32($word2);
  return $r;
}


Здесь 2 эквивалентные реализации функций, во 2-й меньше действий, а 1-я понятнее. Это уже готовые функции, для того чтобы в 1-й оставить только xor необходимо закоментировать условие smile

Автор: admsasha 25.5.2007, 13:04
Если кому интересно.

Код

sub foo{
    $w1=shift;
    $w2=shift;

    $w1 = normal( $w1);^
    $w2 = normal( $w2);^

    $rez= $w1^$w2;
    if($rez >= $maxhalf){
      $rez = -($maxnum-$rez+1);^
      return $rez;
      $rez = $maxnum+$rez+1;^
    }
    return $rez;
}

sub normal {
  my $a = shift;
  my $rez;
  if($a > $maxnum) {
    $rez = $a % $maxnum;
    --$rez;
  } else {
    $rez = $a;
  }
  return $rez
}


Добавлено через 1 минуту и 56 секунд
Ivan Kolesnikov, Странно, но вывод всё равно 

Код

> ./proba.pl
4002146570
4002146570




Автор: Ivan Kolesnikov 25.5.2007, 13:13
admsasha,  я запустил приведенную тобой функцию foo для javascript (вместе с условием в конце) ее результат 4002146570

А вообще твой вариант с остатком от деления лучше моего, так как при больших числах мой вариант будет работать очень долго

Автор: admsasha 25.5.2007, 13:26
Ivan Kolesnikov, интересно.. а какой браузер ?

Автор: Ivan Kolesnikov 25.5.2007, 13:31
Сейчас проверил в IE7, Opera 9, Firefox 2 везде результат один 4002146570.

Запускаю следующую страницу
Код

<script>
function foo(word1,word2) {
    var rez=word1^word2;
    var max32=0xffffffff;
    if ( rez < 0 ) rez = max32 + 1 + rez;
    return rez; 
}
alert(foo(6537379050,1797494240)); 
</script>


Автор: admsasha 25.5.2007, 14:05
Ivan Kolesnikov, Разобрался, это я не так считал...
я в примере то давал только результат word1^word2, а так, да формула вроде верная. Спасибо.


Вообщем тема пока закрыта. Вроде как всё работает. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)