问题
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