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 '20 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 '20 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 '20 at 11:06
  • this one wasn't a well written question, because you just posted it without doing any troubleshooting
    – barlop
    Dec 17 '20 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 '20 at 11:20
75

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 '17 at 8:07
  • 28
    It is pretty well explained I think
    – NanoPish
    Jan 3 '17 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 '17 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 '17 at 17:25
  • 7
    @MaxRied: -1 to your comment for seeking unnecessary fluff
    – user541686
    Jan 4 '17 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
25

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."
    – Scott
    Jan 3 '17 at 16:20
  • 8
    +1 because understanding the order of expansion is very useful for making sense of many different Bash expressions. Jan 3 '17 at 17:20
  • 1
    This could have simply been a comment to Ipor's answer.
    – chepner
    Jan 4 '17 at 2:48
  • 1
    @chepner Please try to squeeze that well-formatted blockquote into a comment :-)
    – Alexander
    Jan 4 '17 at 11:37
  • 1
    "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 '17 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.