Можно ли обрабатывать длинные целые или большие целые числа в (g) awk-скрипте? - PullRequest
4 голосов
/ 29 апреля 2019

Из-за того, что awk обрабатывает все числа с двойной точностью, длинные целые числа (как тип long int или, более часто: long) достигают крыши с 53 битами (или 16,5 цифрами).Это означает, что если программе будет передан long int из архитектуры x86_64, где long int равен 64-битам, у нас будут проблемы.Есть ли в любом случае сценарий awk для обработки этого случая?

На самом деле нельзя использовать -M или -bignum при запуске, так как сценарий слишком велик для сценария awk, и я нехочу изменить общее поведение.Печать с использованием

printf("%d\n",1234567890123456789)

на самом деле не вариант.Даже если все цифры будут напечатаны, точность остается точной только до последнего «7» (12345678901234567 68 ).

Любой, у кого есть предложение, которое не требуетвстроенный питон или perl?

BR Patrik

PS

Я часто видел вопросы по обработке "очень больших целых чисел" или "длинных целых чисел"где «длинный» означает очень большой.Далее, эти вопросы скорее относятся к встроенному awk в bash, где -M не проблема.Однако этот вопрос конкретно относится к обработке типа long int в режиме сценария.

EDIT

Просто чтобы уточнить больше.Вопрос, помеченный как дубликат, не отвечает на мой вопрос, так как я упомянул, что хотел решить это в сценарии, не изменяя поведение awk.Добавление флага -M изменит поведение всех остальных 100 000 строк awk, и я не хочу этого делать.

Другими словами, я хочу, чтобы 99 999 строк awk вели себя так, как если бы флаг -M былне установлено и 1 строка для обработки длинного целого числа.Я хорошо знаю, что это может быть невозможно в awk, но я решил, что попробую здесь, прежде чем сдаться.

1 Ответ

2 голосов
/ 30 апреля 2019

Поскольку вы упоминаете опцию --bignum, я предполагаю, что вы используете gawk.

Я не думаю, что gawk предлагает способ использовать библиотеку MP для одной конкретной строки программы среди тысяч. Но в качестве обходного пути вы можете использовать калькулятор произвольной точности bc в качестве совместного процесса.

Другими словами, вместо:

gawk -v var=123456789012345676890 '
    BEGIN {
        var2 = var + 1
        print var " + 1 = " var2
    }
'

... который ошибочно отображает:

123456789012345676890 + 1 = 123456789012345683968

Вы можете использовать:

gawk -v var=123456789012345676890 '
    BEGIN {
        print var " + 1" |& "bc"
        "bc" |& getline var2
        print var " + 1 = " var2
    }
'

... который будет правильно отображать:

123456789012345676890 + 1 = 123456789012345676891
...