cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Highlighted
Frequent Visitor

Number to Binary

Is it possible to convert numbers to binary data in Power BI?

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Community Champion
Community Champion

Re: Number to Binary

I addition to my previous respons.

 

Some of the things I realized recently, is that:

an "if ... then ... else"  statement with big chunks of code like above, is not required.

 

Thanks to concept of "Lazy Evaluation" in Power Query, you can just put in the code without if...then...else.

Intead, the choice is made later. In the example below: in the Result step.

 

So the inner part of the previous function (which is the actual function without documentation), can be rewritten as:

 

    fnNBC = (input as anynonnull, base as number, optional outputlength as number) as any =>
    let
        //    input = 10,
        //    base = 2,
        //    outputlength = null,
        Base16 = "0123456789ABCDEF",
        Base32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
        Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        Lookups = List.Zip({{16,32,64},{Base16,Base32,Base64}}),
        Lookup = Text.ToList(List.Last(List.Select(Lookups,each _{0} <= List.Max({16, base}))){1}),
        InputToList = Text.ToList(input),

        // This part will be executed if input is text:
            Reversed = List.Reverse(InputToList),
            BaseValues = List.Transform(Reversed, each List.PositionOf(Lookup,_)),
            Indexed = List.Zip({BaseValues, {0..Text.Length(input)-1}}),
            Powered = List.Transform(Indexed, each _{0}*Number.Power(base,_{1})),
            Decimal = List.Sum(Powered),
        // So far this part

        // This part will be executed if input is not text:
            Elements = 1+Number.RoundDown(Number.Log(input,base),0),
            Powers = List.Transform(List.Reverse({0..Elements - 1}), each Number.Power(base,_)),
            ResultString = List.Accumulate(Powers,
                                          [Remainder = input,String = ""], 
                                          (c,p) => [Remainder = c[Remainder] - p * Number.RoundDown(c[Remainder] / p,0),
                                                    String = c[String] & Lookup{Number.RoundDown(c[Remainder]/p,0)}])[String],    
            PaddedResultString = if outputlength = null then ResultString else Text.PadStart(ResultString,outputlength,Lookup{0}),
        // So far this part

        Result = if input is text then Decimal else PaddedResultString
    in
        Result

 

Specializing in Power Query Formula Language (M)

View solution in original post

9 REPLIES 9
Highlighted
Super User IV
Super User IV

Re: Number to Binary

In Power Query you can use Binary.FromText.

http://www.excelandpowerbi.com/?p=291

 


---------------------------------------

Putting square pegs in round holes since 1972.

I have a NEW book! 
DAX Cookbook from Packt
Over 120 DAX Recipes!




Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




Highlighted
Frequent Visitor

Re: Number to Binary

Thanks for the input. I tried using the approach to convert the number '52'  to binary, but can't the expected output of 00110100. Is there another feature I'm missing to use numbers instead of hex or text?

 

Highlighted
Community Champion
Community Champion

Re: Number to Binary

Some time ago I shared a great function on another forum.

 

With this function - fnNumberBaseConversion - you can convert numbers to (almost) any base and vice versa.

Disclaimer: as far as I know, the function works fine, but I can't give any guarantees.

 

Screen shot with the parameters to get 00110100 from 52:

fnNumberBaseConversion.png

 

Result:

FiftyTwoToBinary using fnNumberBaseConversion.png

 

And the code, with complete documentation:

 

let 
    Documentation =
    [Documentation.Category =    "Custom Function",
     Documentation.Description = "Function created by Bemint to convert numbers from or to a specific base",
     Documentation.Examples =    { [Description = "Convert 10 to binary",
                                   Code = "fnNumberBaseConversion(10, 2)",
                                   Result = "10100"],
                                   [Description = "Convert 123456 to hexadecimal with a result length of minimal 8",
                                   Code = "fnNumberBaseConversion(123456, 16, 8)",
                                   Result = "0001E240"]},
     Documentation.LongDescription =
                "fnNumberBaseConversion converts a number to a base string or vice versa.
                 Supported bases are 2 thru 16, 32 and 64.
                 Input is either an integer > 0 that will be converted to a base string or a base string that will be converted to a number.
                 Optionally, outputlength can be supplied to have resulting base strings padded to the desired length"],

    fnNBC = (input as anynonnull, base as number, optional outputlength as number) as any =>
    let
        //    input = 10,
        //    base = 2,
        //    outputlength = null,
        Base16 = "0123456789ABCDEF",
        Base32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
        Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        Lookups = List.Zip({{16,32,64},{Base16,Base32,Base64}}),
        Lookup = Text.ToList(List.Last(List.Select(Lookups,each _{0} <= List.Max({16, base}))){1}),
        InputToList = Text.ToList(input),
        Result = if input is text
        then
        let
            Reversed = List.Reverse(InputToList),
            BaseValues = List.Transform(Reversed, each List.PositionOf(Lookup,_)),
            Indexed = List.Zip({BaseValues, {0..Text.Length(input)-1}}),
            Powered = List.Transform(Indexed, each _{0}*Number.Power(base,_{1})),
            Decimal = List.Sum(Powered)
        in
            Decimal
        else
        let
            Elements = 1+Number.RoundDown(Number.Log(input,base),0),
            Powers = List.Transform(List.Reverse({0..Elements - 1}), each Number.Power(base,_)),
            ResultString = List.Accumulate(Powers,
                                          [Remainder = input,String = ""], 
                                          (c,p) => [Remainder = c[Remainder] - p * Number.RoundDown(c[Remainder] / p,0),
                                                    String = c[String] & Lookup{Number.RoundDown(c[Remainder]/p,0)}])[String],    
            PaddedResultString = if outputlength = null then ResultString else Text.PadStart(ResultString,outputlength,Lookup{0})
        in
            PaddedResultString
    in
        Result,
    // Create FunctionType with metadata at function type level:
    FunctionType = Type.ForFunction([ReturnType = type any, Parameters = [input = type anynonnull, base = type number, outputlength = type number]], 2) meta Documentation,
    fnNumberBaseConversion = Value.ReplaceType(fnNBC,FunctionType)
in
    fnNumberBaseConversion
Specializing in Power Query Formula Language (M)
Highlighted
Community Champion
Community Champion

Re: Number to Binary

I addition to my previous respons.

 

Some of the things I realized recently, is that:

an "if ... then ... else"  statement with big chunks of code like above, is not required.

 

Thanks to concept of "Lazy Evaluation" in Power Query, you can just put in the code without if...then...else.

Intead, the choice is made later. In the example below: in the Result step.

 

So the inner part of the previous function (which is the actual function without documentation), can be rewritten as:

 

    fnNBC = (input as anynonnull, base as number, optional outputlength as number) as any =>
    let
        //    input = 10,
        //    base = 2,
        //    outputlength = null,
        Base16 = "0123456789ABCDEF",
        Base32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
        Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        Lookups = List.Zip({{16,32,64},{Base16,Base32,Base64}}),
        Lookup = Text.ToList(List.Last(List.Select(Lookups,each _{0} <= List.Max({16, base}))){1}),
        InputToList = Text.ToList(input),

        // This part will be executed if input is text:
            Reversed = List.Reverse(InputToList),
            BaseValues = List.Transform(Reversed, each List.PositionOf(Lookup,_)),
            Indexed = List.Zip({BaseValues, {0..Text.Length(input)-1}}),
            Powered = List.Transform(Indexed, each _{0}*Number.Power(base,_{1})),
            Decimal = List.Sum(Powered),
        // So far this part

        // This part will be executed if input is not text:
            Elements = 1+Number.RoundDown(Number.Log(input,base),0),
            Powers = List.Transform(List.Reverse({0..Elements - 1}), each Number.Power(base,_)),
            ResultString = List.Accumulate(Powers,
                                          [Remainder = input,String = ""], 
                                          (c,p) => [Remainder = c[Remainder] - p * Number.RoundDown(c[Remainder] / p,0),
                                                    String = c[String] & Lookup{Number.RoundDown(c[Remainder]/p,0)}])[String],    
            PaddedResultString = if outputlength = null then ResultString else Text.PadStart(ResultString,outputlength,Lookup{0}),
        // So far this part

        Result = if input is text then Decimal else PaddedResultString
    in
        Result

 

Specializing in Power Query Formula Language (M)

View solution in original post

Highlighted
Super User I
Super User I

Re: Number to Binary

I don't get it. All the binary functions seem to expect a binary value or text representing a binary value as the input. I don't see any function anywhere that converts base 10 to base 2.

Edit: seems a solution was presented while I was reading M documentation.





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




Highlighted
Community Champion
Community Champion

Re: Number to Binary

Still a reaction to your now-striked-through-text, just for better understanding:

 

in Power Query, "Binary" means: the binary representation of - for example - file contents, not a binary value as in 1001 = 9.

 

Of course: file contents are also a series of 0's and 1's, but they typically don't represent 1 (huge) decimal value. Smiley LOL

Specializing in Power Query Formula Language (M)
Highlighted
Super User I
Super User I

Re: Number to Binary

Got it. Thanks.





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




Highlighted
Anonymous
Not applicable

Re: Number to Binary

I know it is an old topic, but I just tried to reuse this code snippet, and it does not work for 0 and "0". Has anybody made that correction?

Highlighted
Community Champion
Community Champion

Re: Number to Binary

It should work with "0", but not if the base is 32, which has no "0" in the 32 characters.

 

A small correction to have it work with 0:
in step "Elements" I added a List.Max formula, in order to supply a minimum of 1 as argument to Number.Log.

 

fnNBC = (input as anynonnull, base as number, optional outputlength as number) as any =>
    let
        //    input = 10,
        //    base = 2,
        //    outputlength = null,
        Base16 = "0123456789ABCDEF",
        Base32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
        Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        Lookups = List.Zip({{16,32,64},{Base16,Base32,Base64}}),
        Lookup = Text.ToList(List.Last(List.Select(Lookups,each _{0} <= List.Max({16, base}))){1}),
        InputToList = Text.ToList(input),

        // This part will be executed if input is text:
            Reversed = List.Reverse(InputToList),
            BaseValues = List.Transform(Reversed, each List.PositionOf(Lookup,_)),
            Indexed = List.Zip({BaseValues, {0..Text.Length(input)-1}}),
            Powered = List.Transform(Indexed, each _{0}*Number.Power(base,_{1})),
            Decimal = List.Sum(Powered),
        // So far this part

        // This part will be executed if input is not text:
            Elements = 1+Number.RoundDown(Number.Log(List.Max({1,input}),base),0),
            Powers = List.Transform(List.Reverse({0..Elements - 1}), each Number.Power(base,_)),
            ResultString = List.Accumulate(Powers,
                                          [Remainder = input,String = ""], 
                                          (c,p) => [Remainder = c[Remainder] - p * Number.RoundDown(c[Remainder] / p,0),
                                                    String = c[String] & Lookup{Number.RoundDown(c[Remainder]/p,0)}])[String],    
            PaddedResultString = if outputlength = null then ResultString else Text.PadStart(ResultString,outputlength,Lookup{0}),
        // So far this part

        Result = if input is text then Decimal else PaddedResultString
    in
        Result

 

Specializing in Power Query Formula Language (M)

Helpful resources

Announcements
Community Blog

Community Blog

Visit our Community Blog for articles, guides, and information created by fellow community members.

Using the Community

Using the Community

Need help with the Power BI Community? Our 'Using the Community' support articles are a great place to start.

Community Summit North America

Community Summit North America

Innovate, Collaborate, Grow. The top training and networking event across the globe for Microsoft Business Applications

Power Platform 2020 release wave 2 plan

Power Platform 2020 release wave 2 plan

Features releasing from October 2020 through March 2021

Top Solution Authors
Top Kudoed Authors