Имеет ли большое целое число в AWK только 53 бита?

#c #linux #awk #bit-manipulation

#c #linux #awk #манипулирование битами

Вопрос:

Очень странно, я обнаружил, что в awk большое целое число выглядит так, как будто имеет только 53 бита.Вот мой пример:

 function bits2str(bits,data, mask)
{
    if (bits == 0)
        return "0"

    mask = 1
    for (; bits != 0; bits = rshift(bits, 1))
        data = (and(bits, mask) ? "1" : "0") data

    while ((length(data) % 8) != 0)
        data = "0" data

    return data
}

BEGIN{
    print 32,"tlshift 48:t", lshift(32,48), "t", bits2str(lshift(32,48))
    print 429,"tlshift 48:t", lshift(429,48), "t", bits2str(lshift(429,48))
}
  

и результат:

 32  lshift 48:   0   0
429     lshift 48:   3659174697238528    00001101000000000000000000000000000000000000000000000000
  

но в c его вывод:

 32 lshift 48: 9007199254740992
429 lshift 48: 120752765008871424
  

После сравнения двух выходных данных я обнаружил, что awk имеют только 53 бита,
а затем я исследовал исходный код gawk (начиная со строки 3021 в файле с именем builtin.c, gawk 4.1.1, http://ftp.gnu.org/gnu/gawk /), но я не нашел никакой специальной операции над int.
Итак, что вызывает это? Почему это так?

Ответ №1:

В AWK все числа хранятся с плавающей запятой.

Из побитовой функции:

Для всех этих функций сначала значение с плавающей запятой двойной точности преобразуется в самый широкий целочисленный тип C без знака, затем выполняется побитовая операция. Если результат не может быть представлен точно как C double , начальные ненулевые биты удаляются один за другим, пока он не будет представлен точно. Затем результат преобразуется обратно в C double .

Предполагая, что используется IEEE-754, double s может представлять только целые числа до 2 53.

Ответ №2:

если вы используете gawk, вам нужно добавить -M опцию для большого числа.

 kent$ awk 'BEGIN{print lshift(32,48)}'
0

kent$ awk -M 'BEGIN{print lshift(32,48)}'
9007199254740992
  

Комментарии:

1. Нет, это не работает. У моего gawk / awk нет этой опции. Моя версия awk — GNU Awk 3.1.5, как насчет вас?

2. В своем вопросе вы упомянули, что проверили коды gawk 4.1.1. итак, я тестировал с 4.1.1. Если вы работаете над 3.1.5, почему вы проверили коды 4.1.1? @xingwudao

3. Ага, извините, это такая глупая попытка для меня! Я установлю 4.1.1 на свой компьютер.

4. Спасибо за вашу помощь!