screenslaver
screenslaver

Reputation: 613

How to do binary addition in bash

I am trying to add two 32 bit binary numbers. One of them is a constant (address_range_in_binary) , and another one is an element of an array (IPinEachSubnet[$val])

I am trying to follow the instructions here, but I could not figure out how to get it done using variables. I have been trying to use different combinations of the below, but none of them seems to work. It is probably a simple syntax issue. Any help would be appreciated. The following is printing some negative random values.

For example, if the values are as following:

$address_range_in_binary=00001010001101110000101001000000
$IPinEachSubnet[$val]=00000000000000000000000000010000

echo "ibase=2;obase=2;$((address_range_in_binary+IPinEachSubnet[$val]))" | bc -l

The output of this is -1011101110111111110

Upvotes: 4

Views: 3223

Answers (2)

Diego Torres Milano
Diego Torres Milano

Reputation: 69218

bash only solution

y=2#00001010001101110000101001000000
t=2#00000000000000000000000000010000
oct=$(printf '%o' $(( y + t ))) # no bin format in printf
o2b=({0..1}{0..1}{0..1})
r=''
for (( i=0; i<${#oct}; i++ ))
do
  r+=${o2b[${oct:$i:1}]}
done
echo $r

the conversion from oct to bin is inspired in Bash shell Decimal to Binary conversion

Upvotes: 3

John1024
John1024

Reputation: 113844

Let's define your variables (I will use shorter names):

$ y=00001010001101110000101001000000
$ t=00000000000000000000000000010000

Now, let's run the command in question:

$ echo "ibase=2;obase=2;$((y+t))" | bc -l
-1011101110111111111

The above produces that incorrect result that you observed.

To get the correct result:

$ echo "ibase=2;obase=2; $y+$t" | bc -l
1010001101110000101001010000

Discussion

The command $((y+t)) tells bash to do the addition assuming that the numbers are base-10. The result of bash's addition is passed to bc. This is not what you want: You want bc to do the addition.

Using an array

$ y=00001010001101110000101001000000
$ arr=(00000000000000000000000000010000)
$ echo "ibase=2;obase=2; $y+${arr[0]}" | bc -l
1010001101110000101001010000

Upvotes: 2

Related Questions