How to handle integers in bash with values larger than 2^63

大憨熊 提交于 2020-06-17 01:39:38

问题


It seems like bash's maximum signed integer value is 9223372036854775807 (2^63)-1. Is there a way for bash to handle larger values than this? I need to handle numbers up to 10000000000000000000000000001, but I'm not sure how to accomplish this in bash.

A=10000000000000000000000000000
echo $A
10000000000000000000000000000
let A+=1
echo $A
4477988020393345025

EDIT Thanks Benjamin W. for your comment. Based on that I am trying the following strategy. Are there any perceived issues with this? Meaning, aside from some performance hit due to invoking bc, would there by complications from using bc to increment my variable?

A=10000000000000000000000000000
echo $A
10000000000000000000000000000
A=$(bc <<< "$A+1")
echo $A
10000000000000000000000000001

Also, I've tested some bash operations (greater than, less than, etc) and it seems it behaves as expected. E.g.:

A=10000000000000000000000000000

echo $A
10000000000000000000000000000

[[ "$A" -gt 10000000000000000000000000000 ]] && echo "A is bigger than 10000000000000000000000000000"

A=$(bc <<< "$A+1")

echo $A
10000000000000000000000000001

[[ "$A" -gt 10000000000000000000000000000 ]] && echo "A is bigger than 10000000000000000000000000000"
A is bigger than 10000000000000000000000000000

回答1:


I'd recommend using bc with its arbitrary precision.

Bash overflows at 263:

$ A=$(( 2**63 - 1 ))
$ echo $A
9223372036854775807
$ echo $(( A+1 ))
-9223372036854775808

bc can handle this:

$ bc <<< "$A+1"
9223372036854775808

These numbers have to be handled with bc for everything from now on, though. Using [[ ]], they don't seem to overflow, but comparison doesn't work properly:

$ B=$(bc <<< "$A+1")
$ echo $B
9223372036854775808
$ set -vx
$ [[ $B -gt -$A ]] && echo true
[[ $B -gt -$A ]] && echo true
+ [[ 9223372036854775808 -gt -9223372036854775807 ]]

And in arithmetic context (( )), they overflow:

$ echo $(( B ))
-9223372036854775808

so the comparison doesn't work either:

$ (( B > A )) && echo true || echo false
false

Handling them with bc:

$ bc <<< "$B > $A"
1

and since within (( )) non-zero results evaluate to true and zero to false, we can use

$ (( $(bc <<< "$B > $A") )) && echo true
true


来源:https://stackoverflow.com/questions/51884432/how-to-handle-integers-in-bash-with-values-larger-than-263

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!