2014-01-14 2 views
1

Я думаю, что я столкнулся с какой-то тип переполнения в AWK, и я не уверен, как обойти это, смотрите ниже:Awk Integer Overflow

BEGIN { 
    print 23 * 22 * 21 * 20 * 19 * 18 * 17 * 16 * 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 
    print  22 * 21 * 20 * 19 * 18 * 17 * 16 * 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 
} 

Это выход:

25852016738884978212864 
1124000727777607680000 

Пока второе верно, первое - нет, 23! равен 25852016738884976640000.

Есть ли хоть какой-то вариант, возможно, какой-то вариант?

Чтобы быть точным Я использую Gawk:

GNU Awk 4.0.1 
+0

'awk' делает не претендует на предоставление арифметики произвольной точности. Возможно, вы сможете обойти его, заменив некоторые номера версией с плавающей запятой, но установка «22» на «22.0» фактически не обеспечила желаемого эффекта. Используйте инструмент с арифметикой «бесконечной точности»; 'bc' - один из таких инструментов, Python - другой. –

+3

Если ваша версия 'awk' поддерживает [Arbitrary Precision Arithmetic] (http://www.gnu.org/software/gawk/manual/gawk.html#Arbitrary-Precision-Arithmetic), то есть использует' gmp', вы можете предоставить опцию '-M' для получения желаемых результатов. – devnull

+0

Мне пришлось перекомпилировать gawk с флагами для mpfr, что позволило мне использовать опцию -M. Благодаря! –

ответ

2

используя Ьс

$ echo '23 * 22 * 21 * 20 * 19 * 18 * 17 * 16 * 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1' |bc 

25852016738884976640000 

Вы можете экспортировать результат AWK в команде Ьс:

cat a.awk 

BEGIN { 
    for (i=23;i>1;i--) printf "%d * ",i ; printf 1 RS 
    for (i=22;i>1;i--) printf "%d * ",i ; printf 1 RS 
} 

awk -f a.awk|bc 

25852016738884976640000 
1124000727777607680000