55

The following bash script displays a decimal number when given binary number.

echo $((2#$1))

Why exactly ?

I understand that $1 is the input. Maybe 2 is the base (binary). But I can't understand the syntax used.

6
  • if you understood that $1 was a positional parameter then you should have simplified your question and done just echo $((2#0110)) as you did and got '6'. Then you ask if 2 was the base. Well obviously. And it's not hard to test that. It's no coincidence that echo $((2#0111)) is 7. and $((2#1000))` is 8. You got it for one binary number. So given that, then yeah you got it anyway , obviously
    – barlop
    Dec 16, 2020 at 17:43
  • @barlop I recently edited the question to add the echo $((2#0110)) = 6 part, because I noticed there was no direct example with output in my question and in the answers
    – NanoPish
    Dec 17, 2020 at 10:54
  • Kind of makes a nonsense of the question ('cos if a questioner knew that then they'd know the answer). Though as you know an example is good. It's one of those things where if you'd been careful about asking the question properly in the first place before posting it, so before clicking "submit/post", then you would have ended up solving it yourself easily. Sometimes I start asking a question and i've typed it and refined it but I solve it in the process of asking a good question, so nothing to ask. Other times I solve the question but it's a good question so I post both Q and A.
    – barlop
    Dec 17, 2020 at 11:06
  • this one wasn't a well written question, because you just posted it without doing any troubleshooting
    – barlop
    Dec 17, 2020 at 11:08
  • @barlop well thank you for your opinion, it is very interesting. other users seem to have had another one
    – NanoPish
    Dec 17, 2020 at 11:20

3 Answers 3

76

man bash

   echo [-neE] [arg ...]
          Output  the  args,  separated  by spaces, followed by a newline.
          The return status is 0 unless a write error occurs.   If  -n  is
          specified, the trailing newline is suppressed.  If the -e option
          is given,  interpretation  of  the  following  backslash-escaped
          characters  is  enabled.

[...]

   Arithmetic Expansion
       Arithmetic  expansion allows the evaluation of an arithmetic expression
       and the substitution of the result.  The format for  arithmetic  expan‐
       sion is:

              $((expression))

[...]

   Constants with a leading 0 are interpreted as octal numbers.  A leading
   0x or  0X  denotes  hexadecimal.   Otherwise,  numbers  take  the  form
   [base#]n,  where the optional base is a decimal number between 2 and 64
   representing the arithmetic base, and n is a number in that  base.   If
   base#  is omitted, then base 10 is used.  When specifying n, the digits
   greater than 9 are represented by the lowercase letters, the  uppercase
   letters, @, and _, in that order.  If base is less than or equal to 36,
   lowercase and uppercase letters may be used interchangeably  to  repre‐
   sent numbers between 10 and 35.
12
  • 66
    -1 for ZERO explanation.
    – bot47
    Jan 3, 2017 at 8:07
  • 28
    It is pretty well explained I think
    – NanoPish
    Jan 3, 2017 at 9:19
  • 19
    Fully answering a question, even if "only" by curating existing documentation, does not deserve -1 for me. In particular if that documentation is the manpage of bash.
    – YoungFrog
    Jan 3, 2017 at 10:06
  • 33
    man bash | wc indicates the [GNU bash, version 3.2.57] man page to be 4890 lines, 37094 words, 329778 characters. This answer strips that down to only the 7 lines, 176 words, 1115 characters that are relevant. I think that answer deserves your upvote. (as does this comment ;-) Jan 3, 2017 at 17:25
  • 7
    @MaxRied: -1 to your comment for seeking unnecessary fluff
    – user541686
    Jan 4, 2017 at 6:54
31

From the Doc at: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

Constants with a leading 0 are interpreted as octal numbers. A leading ‘0x’ or ‘0X’ denotes hexadecimal. Otherwise, numbers take the form [base#]n, where the optional base is a decimal number between 2 and 64 representing the arithmetic base, and n is a number in that base. If base# is omitted, then base 10 is used. When specifying n, the digits greater than 9 are represented by the lowercase letters, the uppercase letters, ‘@’, and ‘_’, in that order. If base is less than or equal to 36, lowercase and uppercase letters may be used interchangeably to represent numbers between 10 and 35.

So echo $((16#FF)) outputs 255 and echo $((2#0110)) outputs 6

0
26

Ipor's answer is excellent but very slightly incomplete. The quoted part of the bash man page states that the [base#]n syntax works only for constants, and 2#$1 is not a constant. You should be asking how this really works!

EXPANSION

    Expansion is performed on the command line after it has been split into words.  There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.

    The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.

Basically Bash is doing variable substitution first, so that the $1 is first replaced with its value. Only then does it do arithmetic expansion, which sees only a proper constant.

5
  • This seems unnecessary; the OP says, "I understand that $1 is the input." Jan 3, 2017 at 16:20
  • 9
    +1 because understanding the order of expansion is very useful for making sense of many different Bash expressions. Jan 3, 2017 at 17:20
  • 1
    This could have simply been a comment to Ipor's answer.
    – chepner
    Jan 4, 2017 at 2:48
  • 1
    @chepner Please try to squeeze that well-formatted blockquote into a comment :-)
    – Alexander
    Jan 4, 2017 at 11:37
  • 2
    "Note that the parameter $1 is expanded to produce an integer constant before the arithmetic expression is evaluated. See gnu.org/software/bash/manual/bash.txt, section 3.5"
    – chepner
    Jan 4, 2017 at 13:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .