简体   繁体   中英

High value variable in Linux

I want to read a binary number that can be of any length from 1 to 32 digits.

Example: 1, 10, 101, 10000001....10000000100000001000000010000000

Now, what I want to do is to count the place of all the occurrences of 1 and ADD them.

Example: 10001000 (8 digits number)

Going by binary first 1 comes in at 3rd position and second 1 comes in at 7th position.

What I want is finally get the result 10 (ie 7+3)

Sample Input:

10001000
100100
1000000000101
10010000001
100000001

Sample Output:

10
7
14
17
8

Note: Number can be upto 32 digits.

My Code :

  while read line
  do
       count1=0
       count2=0
       while [ $line -gt 0 ]
       do
            if (($line % 2 == 0))
            then
                    count2=$(($count2+1))
                    line=$(($line/10))
            else
                    line=$(($line/10))
                    count1=$(($count1+$count2))
                    count2=$(($count2+1))
            fi
       done
       echo $count1
    done < h2b.csv >> bit_count.csv

h2b.csv is Input file and bit_count is output file.

This works for smaller values like 1001,1010,1100 but fails to run large value number with more than 16 digits.

Error Message when i run my script:

line 7: [: 1000000000000000000000: integer expression expected

Using Awk

With this as the sample input:

$ cat input
10001000
100100
1000000000101
10010000001
100000001

We can calculate the result with:

$ awk -F '' '{x=0; for (i=NF;i>0;i--) if ($i) x+=NF-i; print x}' input
10
7
14
17
8

How it works

  • -F ''

    This tells awk to treat each character as a separate field.

  • x=0

    This initializes the variable x to zero.

  • for (i=NF;i>0;i--) if ($i) x+=NF-i

    This adds up the total.

  • print x

    This prints the total for this line.

Example with a very long line

The line in this file is 106 characters long:

$ cat >input2
1000100010010010001000100000000100000100000000001000000000000110000000000001100000000000100000000110000001
$ wc input2
  1   1 107 input2
$ awk -F '' '{x=0; for (i=NF;i>0;i--) if ($i) x+=NF-i; print x}' input2
1035

Using Bash

With the same logic:

while read -r line
do
    x=0
    for ((i=${#line};i>0;i--))
    do
        [ ${line:$i-1:1} = 1 ] && ((x+=${#line}-i))
    done
    echo $x
done <input

This produces the output:

10
7
14
17
8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM