1

This outputs 101110

echo "obase=2; 46" | bc

How can I make it output 8 digits, like this? : 00101110

I learned the above usage of bc here: Bash shell Decimal to Binary base 2 conversion

See also my answer to that question here.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265

3 Answers3

2

The simple solution is to use the output of bc within a command substitution providing input to printf using the "%08d" conversion specifier, e.g.

$ printf "%08d\n" $(echo "obase=2; 46" | bc)
00101110
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Oh my goodness! I can't believe I didn't think of that! That's so much easier! It didn't occur to me because `101110` is _not_ a decimal (`%d`) integer number (and in C, which my mind focuses on more, this would be a string, which *really* isn't a decimal number!). Yet...technically, in bash at least, the string `101110` _can be_ / is a decimal number, and `printf` in bash is ok treating it like one, so this works. – Gabriel Staples Mar 22 '22 at 08:03
  • Also, as a lawyer, how do you have so much time to write code, and how did you get so skilled at it? Is it a hobby you do at work? – Gabriel Staples Mar 22 '22 at 08:05
  • 1
    Sometimes it's just the luck of the draw. I made friends with `printf` a long time ago in C, so it's kinda the go-to for formatting wanted integer (or binary) output in this case. Since we are talking less than 8 digits, you can treat the binary output with a leading `1` as an integer `:)` – David C. Rankin Mar 22 '22 at 08:05
  • 1
    Everybody needs a diversion. Since I was an engineer before becoming a lawyer (25 years ago), it's nice to actually deal in a topic that is black-and-white now and again. – David C. Rankin Mar 22 '22 at 08:07
  • By the way, here is my `printf` version which [I had come up with here](https://stackoverflow.com/a/71568273/4561887): `printf "0b%s\n" "$(echo "obase=2; $((num1 + num2))" | bc)"`. I was thinking of the output of `bc` as a string, not a decimal integer. – Gabriel Staples Mar 22 '22 at 08:17
  • 1
    That works too. The reason I prefer the integer conversion specifier is that it allows for both a zero-padding and field-width modifier. Treated as a string, you are limited to the field-width modifier. You can still add the fixed `"0b"` prefix if you like. Good luck with your scripting! – David C. Rankin Mar 22 '22 at 08:20
  • 1
    Another option is to use your string-specifier with an 8-character field width and then do a global replacement of spaces to `0`, e.g. `str=" 101110"; str="${str// /0}"` – David C. Rankin Mar 22 '22 at 08:24
1

Some other solutions:

echo "obase=2; 46" | bc | awk '{ printf("%08d\n", $0) }'
echo "obase=2; 46" | bc | numfmt --format=%08f
phuclv
  • 37,963
  • 15
  • 156
  • 475
0

If there's an easier way I'd like to know, but here's a function I just wrote that does it manually:

decimal_to_binary_string.sh: (from my eRCaGuy_hello_world repo)

# Convert a decimal number to a binary number with a minimum specified number of
# binary digits
# Usage:
#       decimal_to_binary <number_in> [min_num_binary_digits]
decimal_to_binary() {
    num_in="$1"
    min_digits="$2"
    if [ -z "$min_chars" ]; then
        min_digits=8  # set a default
    fi

    binary_str="$(echo "obase=2; 46" | bc)"

    num_chars="${#binary_str}"
    # echo "num_chars = $num_chars" # debugging
    num_zeros_to_add_as_prefix=$((min_digits - num_chars))
    # echo "num_zeros_to_add_as_prefix = $num_zeros_to_add_as_prefix" # debugging
    zeros=""
    for (( i=0; i<"$num_zeros_to_add_as_prefix"; i++ )); do
        zeros="${zeros}0"  # append another zero
    done

    binary_str="${zeros}${binary_str}"
    echo "$binary_str"
}

# Example usage
num=46
num_in_binary="$(decimal_to_binary "$num" 8)"
echo "$num_in_binary"

Output:

00101110
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265