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

Очень странно, я обнаружил, что в 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, начальные ненулевые биты удаляются один за другим, пока он не может быть представлен точно. Результат затем конвертируется обратно в C двойной.

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

2

Другие решения

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

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector