3
$\begingroup$

How to use summation to get the value of a binary number?

I want to do this:

$(x_{n}x_{n-1}...x_{0})=\sum_{i=0}^{n}x_{i}\cdot b^{i} $

But it seems that I can only do something like this:

$\sum_{i=1}^{10}i^{2}$

I imagine that there is some indexation function which will help to do so, I also know how to do in another way, but is it possible to do this using summation?

$\endgroup$
9
  • 4
    $\begingroup$ I'm not sure I get what you're trying to do... express a binary number in its decimal form? Your equations aren't... equations. The expression in parentheses looks more like a factorial than your summation. $\endgroup$
    – CHM
    Commented May 20, 2012 at 18:17
  • 1
    $\begingroup$ Please give us some working resp. non-working Mathematica code showing what you want. Especially the form in which your input is given. $\endgroup$
    – celtschk
    Commented May 20, 2012 at 18:23
  • $\begingroup$ @CHM Yes. The equation is from this book. $\endgroup$
    – Red Banana
    Commented May 20, 2012 at 18:24
  • 2
    $\begingroup$ @GustavoBandeira Your comment is not helpful. $\endgroup$
    – Artes
    Commented May 20, 2012 at 18:26
  • $\begingroup$ @celtschk I want to decompose the binary number and get it on decimal form. Like this: $1001 \rightarrow1\cdot 2^{3}+0\cdot 2^{2}+0\cdot 2^{1}+1\cdot 2^{0}$ $\endgroup$
    – Red Banana
    Commented May 20, 2012 at 18:29

5 Answers 5

10
$\begingroup$
binDigits = {1, 0, 1, 1, 1, 1, 1, 0};

Alternative 1:

binDigits.Table[2^i, {i, Length[binDigits] - 1, 0, -1}]

(* ==> 190 *)

Alternative 2:

Sum[2^(Length[binDigits] - i) binDigits[[i]], {i, Length[binDigits]}]

(* ==> 190 *)

Alternative 3:

FromDigits[binDigits, 2]

(* ==> 190 *)

If your binary number is given as a string you could do the following first:

binDigits = ToExpression /@ Characters["10111110"]

(* ==> {1, 0, 1, 1, 1, 1, 1, 0} *)

If your binary number is given as a decimal numbers with 1's and 0's only (actually a misrepresentation) you could try:

binDigits = ToExpression /@ Characters@ToString@10111110

(* ==> {1, 0, 1, 1, 1, 1, 1, 0} *)
$\endgroup$
6
  • $\begingroup$ But isn't it possible with summation? $\endgroup$
    – Red Banana
    Commented May 20, 2012 at 18:34
  • 2
    $\begingroup$ @GustavoBandeira I clearly see a summation in there. Try looking again (alternative 2). $\endgroup$ Commented May 20, 2012 at 18:34
  • 1
    $\begingroup$ "Alternative 1" could have been written more compactly as binDigits .2^Range[Length[binDigits] - 1, 0, -1]. Still, if a function like FromDigits[] did not exist in Mathematica, the two other alternatives do a bit too much arithmetic for the purpose; one would usually prefer Horner's method for this: Fold[(2 #1 + #2) &, 0, binDigits]. $\endgroup$ Commented May 20, 2012 at 21:42
  • $\begingroup$ I agree with J.M. If Sum is mandatory, how about i = 0; Sum[2^(i++) d, {d, Reverse@binDigits}] :-) $\endgroup$
    – Mr.Wizard
    Commented May 21, 2012 at 9:29
  • $\begingroup$ @Mr.Wizard With the question vague as it was, I din't want to spend too much time on this, or it might have been for naught. Also, all the fancy stuff may be quicker to execute or shorter to write, but it is harder to grasp for beginners. $\endgroup$ Commented May 21, 2012 at 10:41
4
$\begingroup$

A solution using the product of the binary digits and the relevant power of the chosen base:

Clear[s];
Options[s] := {Base -> 2, Totalled -> True};
s[number_, OptionsPattern[]] := 
 With[{digitVals = 
    Reverse@Flatten@
       NestList[# OptionValue@Base &, {1}, Length@number - 1] number},
   If[OptionValue@Totalled, Total@digitVals, digitVals]]

Sample input and output using IntegerDigits to obtain a list representation of a decimal number as binary:

s[IntegerDigits[100, 2], Base -> 2, Totalled -> True]
s[IntegerDigits[100, 2], Base -> 2, Totalled -> False]

(*  

-> 100
-> {64, 32, 0, 0, 4, 0, 0}

*)
$\endgroup$
4
$\begingroup$

I offer this paragon of elegance and readability:

binDigits = {1, 0, 1, 1, 1, 1, 1, 0}
Total@MapIndexed[#1*2^(Length@binDigits - First@#2) &, binDigits]
(*190*)

(or we could use BaseForm).

$\endgroup$
3
$\begingroup$

It seems you want to use the somation notation?

 binDigits = ToExpression /@ Characters["111"]

\!\(
\*UnderoverscriptBox[\(\[Sum]\), \(i = 1\), \(Length[
   binDigits]\)]\(binDigits[[i]]\ 
\*SuperscriptBox[\(2\), \(Length[binDigits] - i\)]\)\)

gives:

Mathematica graphics

And calculates to the answer 7.

$\endgroup$
2
  • $\begingroup$ No, I want to decompose the binary number and get it on decimal form. Like this: $1001 \rightarrow1\cdot 2^{3}+0\cdot 2^{2}+0\cdot 2^{1}+1\cdot 2^{0}$ $\endgroup$
    – Red Banana
    Commented May 20, 2012 at 18:33
  • $\begingroup$ You probably want to use IntegerDigits instead of Characters. That way you can compute with them as numbers. $\endgroup$
    – DavidC
    Commented May 20, 2012 at 20:36
1
$\begingroup$

Most of the answers so far assume that the input is a list of integers representing the digits. As the original question didn't specify the form of the input, here some alternatives.

Taking a string as input

Of course the simplest way to turn a string of binary digits into a number is

fromBinary[s_String] /; StringMatchQ[s,RegularExpression["[01]+"]] :=
  ToExpression["2^^" <> s]

(the complicated part here just checks that the string indeed contains a binary number).

However that would not involve an explicit summation (well, somewhere internally it probably does, but that's hidden), therefore I give another solution containing an explicit sum:

fromBinary[s_String] /; StringMatchQ[s,RegularExpression["[01]+"]] :=
  Total[2^(StringLength[s]-StringPosition[s,"1"][[All,1]])]

The explicit sum is in the call of Total which just adds up all elements in the list given to it.

Taking an integer as input

OK, now I'm assuming that the input is given as an integer whose decimal digits match the binary digits of the intended number (i.e. when given the number 1001 — that is, one thousand and one — it interprets it as the digit sequence 1, 0, 0, 1). Of course, given the function above, it's easy to do that (I omit the binary check here):

fromBinary[i_Integer] := fromBinary[IntegerString[i]]

Another alternative would be to use IntegerDigits[i] and feed the result into the code given in the previous answers.

$\endgroup$
2
  • $\begingroup$ "All the answers so far assume that the input is a list of integers representing the digits". Not true, I offered solutions for string, numeric and list inputs. Please look at the bottom of my post. $\endgroup$ Commented May 20, 2012 at 20:29
  • $\begingroup$ @SjoerdC.deVries: Ah, indeed, I didn't see that. However, given that my solutions (except for the last one which I only sketched) do not turn the input into a list, they still add something. I now changed the beginning of my post accordingly. $\endgroup$
    – celtschk
    Commented May 20, 2012 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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