Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Побитовый сдвиг, на очень больших числах 
V
    Опции темы
Pfailed
Дата 7.8.2009, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: нет
Всего: 39



Суть проблемы такова, что на больших числах (> 32 бит) JavaScript очень странно обрабатывает оператор побитового сдвига.
Приведу пример:
4641394638>>13

Попробуем сделать сдвиг вручную, переведем 4641394638 в двоичную систему счисления:
100010100101001100000111111001110
Сдвинем на 13 вправо:
10001010010100110000
Переведем в десятичную систему счисления:
566576
Итого правильный ответ 566576.

Но вот что  на код:
Код

alert(4641394638>>13);

выдает JavaScript: 42288

Каков же алгоритм расчета побитового сдига у JavaScript для чисел > 32 бит ?



--------------------
PM MAIL   Вверх
IDVsbruck
Дата 7.8.2009, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 778
Регистрация: 12.11.2006

Репутация: 8
Всего: 22



10 секунд экспериментов и результат: откидываются разряды левее 32-го. То есть вместо твоего 10001010010100110000 получится 1010010100110000, а это как раз и есть 42288 ...
Где-то муссировалась тема обхода этого ограничения.
PM MAIL   Вверх
Pfailed
Дата 7.8.2009, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: нет
Всего: 39



IDVsbruck, спасибо 
Тоже догадался поэксперементировать, правда это заняло пару часов а не 10 секунд  smile 
Собственно нужно было понять его алгоритм чтобы воплотить в другом языке программирования (Perl).
Все получилось. Перед сдвигом операнды нужно прогнать через преобразующую функцию, которая у меня получилось такой:
Код

sub to32bit
{
    my $number = shift;
    my $negative;
    
    if($number < 0)
    {
        $negative = 1;
        $number = abs $number;
    }
    
    $number = Math::BigInt->new($number);
    my $bin = substr($number->as_bin, 2);
    
    my $len = length $bin;
    return $negative ? -$number : $number if($len<32);
    
    $bin = substr($bin, $len-32);
    my ($n, $bin) = $bin =~ /(\d)(\d+)/;
    
    if($n == 1)
    {
        $negative = !$negative;
        $bin = join('', map(!$_+0, split('', $bin)));
        return $negative ? -(Math::BigInt->new("0b$bin")+1) : Math::BigInt->new("0b$bin")+1;
    }
    
    return $negative ? - Math::BigInt->new("0b$bin") : Math::BigInt->new("0b$bin");
}



--------------------
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0844 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.