Negative decimal to binary

Is there a fast way to convert a negative decimal value into a signed binary number in bash script ? I've looked a lot on internet but I saw nothing... (For exemple : -1 become 11111111.)

You could use XOR but here is a solution that is fully POSIX complaint:

#!/usr/local/bin/dash
# decimal2binary.sh <integer_-128_to_127>
#
# USAGE: [/full/path/to/][./]decimal2binary.sh <integer_from_-128_to 127>

NUMBER=${1}
STRING=""
PREFIX=0

# Account for -127 to -1.
if [ ${NUMBER} -ge -127 ] && [ ${NUMBER} -le -1 ]
then
    NUMBER=$(( NUMBER + 256 ))
    PREFIX=1
fi

# Account for -128.
if [ ${NUMBER} -eq -128 ]
then
    STRING=10000000
    echo "${STRING}"
    exit
fi

# Now do calculations for positive values only.
for COUNT in 6 5 4 3 2 1 0
do
    M=$(( NUMBER / 2 ))
    N=$(( NUMBER % 2 ))
    NUMBER=${M}
    STRING=$( printf "%d" "${N}" )${STRING}
done

# Print it, no need to reverse the string...
echo "${PREFIX}${STRING}"

Results, OSX 10.14.6, default bash terminal calling dash, POSIX compliant.

Last login: Sat Nov 23 22:28:58 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./decimal2binary.sh 0
00000000
AMIGA:amiga~/Desktop/Code/Shell> ./decimal2binary.sh -128
10000000
AMIGA:amiga~/Desktop/Code/Shell> ./decimal2binary.sh -127
10000001
AMIGA:amiga~/Desktop/Code/Shell> ./decimal2binary.sh -1
11111111
AMIGA:amiga~/Desktop/Code/Shell> ./decimal2binary.sh 1
00000001
AMIGA:amiga~/Desktop/Code/Shell> ./decimal2binary.sh 126
01111110
AMIGA:amiga~/Desktop/Code/Shell> ./decimal2binary.sh 127
01111111
AMIGA:amiga~/Desktop/Code/Shell> _
D2B=({0,1}{0,1}{0,1}{0,1}{0,1}{0,1}{0,1}{0,1})
echo ${D2B[-127]}
1 Like
D2B=($(eval echo $(printf %.s\{0,1} {0..15})))

Please check this (above) for accuracy... thanks.

1 Like

What keeps you from using / trying the proposals in your other thread to the same topic, e.g. this one ?

Nice and I thanked the post but...
Be aware, this only works in ksh93 and zsh on Apple gear.
'bash 3.2.x which is all we have with Apple, and POSIX' is a non-starter.

2 Likes
[nez@rox unix]$ D2B=($(eval echo $(printf %.s\{0,1} {0..15})))
[nez@rox unix]$ echo ${D2B[127]}
0000000001111111
[nez@rox unix]$ echo ${D2B[-127]}
1111111110000001
[nez@rox unix]$ echo ${D2B[1]}
0000000000000001 
[nez@rox unix]$ echo ${D2B[-1]}
1111111111111111
[nez@rox unix]$ echo ${D2B[32767]}
0111111111111111
[nez@rox unix]$ echo ${D2B[-32767]}
1000000000000001
[nez@rox unix]$ bash --version
GNU bash, вер�и� 5.0.7(1)-release (x86_64-redhat-linux-gnu)

invert and add one, everything is correct.
possibly this?

D2B=($(eval echo $(printf %.s'{0,1}' {0..15})))

You should still be able to do:

$ D2B=({0,1}{0,1}{0,1}{0,1}{0,1}{0,1}{0,1}{0,1})
$ echo ${D2B[256-127]}

or

$ echo ${D2B[${#D2B[*]}-127]}
1 Like

Hi Chubler_XL...

I have never seen that before, thanks a lot.
Just shows how much I don't know. Once seen never forgotten...
(But sadly, it won't work in dash.)