4
$\begingroup$

I am struggling on how to create a function that converts a number into binary and then back. I know there is a built-in function about this BaseForm[] but I am trying not to use it. I started thinking about using the RealDigits[] but I don't really know where to go from here. I will keep trying and post any code I do. If anyone can help me with this I would be really grateful. Thanks.

$\endgroup$
4
  • $\begingroup$ Welcome to the Mathematica Stack Exchange. Out of curiosity, why would you not want to use the built-in functions? $\endgroup$
    – Syed
    Apr 4, 2022 at 18:21
  • $\begingroup$ Thanks! I am a beginner in Mathematica and following a course. There is a exercise in which I am not allowed to use BaseForm[] sadly. $\endgroup$
    – peter21
    Apr 4, 2022 at 18:23
  • $\begingroup$ Homework questions are welcome, if you show your meaningful work so far and ask a specific question. $\endgroup$
    – Syed
    Apr 4, 2022 at 18:26
  • $\begingroup$ I usually use IntegerDigits[] and FromDigits[], but if this is homework, then it probably asks you to calculate the digits not using the built-in functions. In this case, you will probably want Mod[m,n] (modulo operation, reminder) and Floor[m/n] (integer part after the division). $\endgroup$
    – mszynisz
    Apr 4, 2022 at 18:47

2 Answers 2

2
$\begingroup$

Just to illustrate ways to do you own way:

Binarize integer:

binary[n_] := 
 Reverse@NestWhileList[
    QuotientRemainder[#[[1]], 2] &, {n}, # != {0, 0} &][[2 ;; -2, 2]]

This produces a list, e.g. binary[23] yields: {1, 0, 1, 1, 1}.

You can invert:

frombinary[n_] := 
With[{k = Length[n]}, n . PowerRange[2^(k 
- 1), 1, 1/2]]

If you want create output like BaseForm:

bf[n_] := Subscript[Row[binary[n]], 2]

You can invert this by accessing list, e.g.

bf2d[n_] := frombinary[(n[[1, 1]])]

where input is Subscript[Row[...]],

The in-built functions are optimized. I present this to motivate "create your own" play.

Update/Edit

In response to comment:

binary[n_] := 
 Reverse@NestWhileList[
    QuotientRemainder[#[[1]], 2] &, {n}, # != {0, 0} &][[2 ;; -2, 2]]
binary[0] = {0};
dec[n_] := 
 NestWhileList[
   Reverse@MixedFractionParts[2 #[[1]]] &, {n}, # != {0, 
      0} &][[2 ;; -2, 2]]
anybin[n_] := 
 Module[{i = IntegerPart[n], f = FractionalPart[n]}, 
  Subscript[Row[Join[binary[i], {"."}, dec[f]]], 2]]

Comparing with BaseForm:

Table[{j, BaseForm[j, 2], 
   anybin[j]}, {j, {0.5, 1.25, 3.75, 1.2, 0.13}}] // 
 TableForm[#, TableHeadings -> {None, {"n",  "BaseForm","anybin"}}] &

enter image description here

Noting: fractions such as 1/5 do not have binary finite representations.

e.g.

Sum[2^(-4 j + 1) + 2^(- 4 j), {j, 1, 3}] // N
Limit[Sum[2^(-4 j + 1) + 2^(- 4 j), {j, 1, x}], x -> Infinity]

They are recurring. This could truncated to show repeating sequence. I leave that to enthusiast.

$\endgroup$
3
  • $\begingroup$ It's a (+1) from me, but a relevant comment: the binary[0.13] does not work and this was pointed out by the author of the OP under my reply in the comments. Perhaps you'd like to update your answer $\endgroup$
    – bmf
    Apr 9, 2022 at 4:43
  • $\begingroup$ @bmf thank you. I apologize for not reading OP question well enough. As I wrote in answer "Binarize integer". However, I take your point. $\endgroup$
    – ubpdqn
    Apr 9, 2022 at 4:46
  • $\begingroup$ yes, of course I understand. And my comment was only meant to serve as hint for an improvement. I do find your answer very good indeed :) $\endgroup$
    – bmf
    Apr 9, 2022 at 4:48
1
$\begingroup$

Edit: addressing the comment

Updated code is:

test[xx_, digits_: 17] := If[xx >= 1,
    ToString@Row@Insert[#1, ".", #2 + 1] & @@ 
   RealDigits[xx, 2, digits], 
  ToString@Row@
    Join[{0}, 
     Insert[Join[
       ConstantArray[0, Abs[RealDigits[xx, 2, digits][[2]]]], 
       RealDigits[xx, 2, digits][[1]]], ".", 1]]]

Checks:

tests



Original answer below:


To binary


tobinary[realnum_] := 
 ToString@Row@Insert[#1, ".", #2 + 1] & @@ RealDigits[#, 2] &[realnum]

And we have

Table[tobinary[ii], {ii, 0, 4, 1}]

b

which can be compared with

Table[BaseForm[i, 2], {i, 0, 4}]

bb

Works also for

tobinary[17.27]

rd


From binary


frombinary[mynumber_] := FromDigits[RealDigits[mynumber], 2]

Quick check:

frombinary[100]

fb

And works also for

frombinary[10001.010001010001111010111000010100011110101110000101] // 
 N

rd2


$\endgroup$
5
  • $\begingroup$ Thanks. Is there a way for it to work for lowers decimals? Because when I try using for example 0.23 it doesn't work. Thanks $\endgroup$
    – peter21
    Apr 5, 2022 at 21:18
  • $\begingroup$ @peter21 you might want to look at the edited version. The key was to understand the output of RealDigits[0.21, 2, 11] $\endgroup$
    – bmf
    Apr 5, 2022 at 22:40
  • $\begingroup$ @peter21 so, does the updated version work as you were expecting? $\endgroup$
    – bmf
    Apr 7, 2022 at 3:38
  • $\begingroup$ yep works perfectly thanks! $\endgroup$
    – peter21
    Apr 7, 2022 at 3:40
  • $\begingroup$ @peter21 thanks for letting me know :) $\endgroup$
    – bmf
    Apr 7, 2022 at 3:43

Your Answer

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

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