Bash script problems int to binary

Hi, I am trying to do a bash script that convert a decimal number to a binary value, but it doesn't work...
To begin, I am just trying to convert a positive number to 8 bits binary.

read -p"Entrez un nombre entre -128 et 127 pour l'encoder en binaire: " number
binaryValues=(128 64 32 16 8 4 2 1)
binaryNumber=()
positiveNum=$number
if [ $number -lt 0 ] #transformer la copie du nombre en positif.
then
(( positiveNum=$number-$number*2 )) 
fi
for i in "${binaryValues[@]}"
do
if (( $positiveNum -ge ${binaryValues} ))
then
positiveNum=$"(( $positiveNum-${binaryValues} ))"
binaryNumber='1';
else
binaryNumber='0';
fi
done
echo ${binaryNumber[@]}

Greetings and welcome,

Is this homework or classwork? As we have a special forum for that purpose with its own rules you have to comply with...

Q: Why have you ommited the value 0 (zero) as binary value?

If you are using

for i in "${binaryValues[@]}"

; then i will contain the value, not the array index in every iteration
-ge is incorrect syntax within (( ... )) , that should be >=
$"((...))" is incorrect usage of quotes, that should be: $((...))

you could write a bash function like this:

dec2bin () {
  # dec2bin num [width] [var]
  local num bin=""
  for((num=$1;num;num/=2))
  do
    bin=$((num%2))$bin
  done
  ((${#3})) &&
      printf -v ${3} "%0*d" ${2:-1} $bin ||
      printf "%0*d\n" ${2:-1} $bin
}

# example calls
dec2bin 59
dec2bin 59 8
dec2bin 23 5 test
echo 23 in binary is $test

output:

111011
00111011
23 in binary is 10111

One wonders why if this is not homework.

How about using what's already available and set the length like this:-

#!/bin/bash

number_in=123
length=20              # Perhaps this is ridiculous, but it proves the point.

number_out=$(echo "obase=2 ; print $number_in" | bc)
printf "%0${length}d\n" "${number_out}"

I hope that this helps,
Robin

Please be aware that

if [ $number -lt 0 ] #transformer la copie du nombre en positif.
then
(( positiveNum=$number-$number*2 )) 
fi

doesn't fly; e.g.

 127d = 01111111b
-127d = 10000001b

That's how (most) computers represent integers: two's complement.

1 Like

A quicky demo for 0 to 127 only using OSX 10.14.6, default 'bash' version 3.2.x...
Called as [./]decimal2binary.sh <integer_from_0_to_127> ...

#!/bin/bash
# decimal2binary.sh <integer_0_to_127>
NUMBER=${1}
STRING=""
for COUNT in 6 5 4 3 2 1 0
do
    M=$(( NUMBER / 2 ))
    N=$(( NUMBER % 2 ))
    NUMBER=${M}
    STRING=${STRING}$( printf "%d" "${N}" )
done
echo "0${STRING:6:1}${STRING:5:1}${STRING:4:1}${STRING:3:1}${STRING:2:1}${STRING:1:1}${STRING:0:1}"

For values -1 to -128 take a look at using binary XOR "relative to zero" for example "-1" becomes binary "11111111"

AMIGA:amiga~> XORED=$(( 00000000 ^ 11111111 ))
AMIGA:amiga~> echo "-1 = ${XORED} relative to the positive value 00000000..."
-1 = 11111111 relative to the positive value 00000000...
AMIGA:amiga~> _

I think adding any negative numbers to 256 should get the desired result.

(I believe this should work OK in bash 3.2.x but dont have that version to confirm).

# decimal2binary.sh <integer_-127_to_127>
dec2bin () {
  # dec2bin num [width] [var]
  local num bin=""
  for((num=$1;num;num/=2))
  do
    bin=$((num%2))$bin
  done
  ((${#3})) &&
      printf -v ${3} "%0*d" ${2:-1} $bin ||
      printf "%0*d\n" ${2:-1} $bin
}

[ $1 -lt 0 ] &&
   dec2bin 256+$1 8 ||
   dec2bin $1 8
1 Like

How about

$ BITS=16
$ VALUE=-127
$ for ((i=BITS; --i>=0;)); do printf "%d" $(( ${VALUE%%[0-9]*}(VALUE>>i)%2 )); done; printf "\n"
1111111110000001
1 Like