Results 1 to 20 of 20

Thread: Decimal to Binary - Optimising

  1. #1

    Thread Starter
    Fanatic Member x-ice's Avatar
    Join Date
    Mar 2004
    Location
    UK
    Posts
    671

    Resolved Decimal to Binary - Optimising

    How can i optimise (or just make it better) this code?
    VB Code:
    1. Option Explicit On
    2. Option Strict On
    3.  
    4. Imports System.Math
    5.  
    6. Public Class clsNumConv
    7.     Public Function Dec2Bin(ByVal DecNum As Int32, ByVal ShowDecNum As Boolean) As String
    8.         Dim DivNum As Int32
    9.         'Establish how many divisions will be done, +1 for number rounding
    10.         DivNum = CInt(Log(DecNum) / (Log(2)) + 1)
    11.         'Create array with number of columns needed according to 'DivNum'
    12.         Dim BinNums(DivNum, 2) As Int16
    13.         'Assign 'DecNum' to columns 1, row 0 of array
    14.         BinNums(0, 1) = CShort(DecNum)
    15.         Dim intRowNum As Int32 = 1 'Divisions loop counter
    16.         Dim RevBinNum As String
    17.         'Calculate divisions
    18.         For intRowNum = 1 To UBound(BinNums) 'To highest subscript of array
    19.             'Divide previous value by 2
    20.             BinNums(intRowNum, 1) = CShort(Math.Floor(BinNums(intRowNum - 1, 1) / 2))
    21.             'Calculate modulus
    22.             BinNums(intRowNum, 2) = CShort(BinNums(intRowNum - 1, 1) Mod 2)
    23.             'Make binary number string
    24.             RevBinNum &= CStr(BinNums(intRowNum, 2))
    25.         Next
    26.         Dim FinalBinNum As String
    27.         'Assign string to 'strBin'" (reverse the string, as the binary number is backwards)
    28.         FinalBinNum = StrReverse(RevBinNum)
    29.         'Remove leading zeros
    30.         FinalBinNum = FinalBinNum.TrimStart("0"c)
    31.         'Check "ShowDecNum" to establish whether or not to show original number
    32.         If ShowDecNum = True Then
    33.             'Output binary number, along with original decimal number
    34.             Return DecNum & "^10" & " = " & FinalBinNum & "^2"
    35.         Else
    36.             'Output binary number
    37.             Return FinalBinNum & "^2"
    38.         End If
    39.     End Function
    40. End Class
    Last edited by x-ice; Jul 24th, 2005 at 08:55 AM.

  2. #2
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Decimal to Binary - Optimising

    I don't know about .NET... but if you want any ideas check out my "Dumpbits" function in codebank, which does binary output of numbers and strings. Link in my sig

  3. #3

    Thread Starter
    Fanatic Member x-ice's Avatar
    Join Date
    Mar 2004
    Location
    UK
    Posts
    671

    Re: Decimal to Binary - Optimising

    Quote Originally Posted by penagate
    I don't know about .NET... but if you want any ideas check out my "Dumpbits" function in codebank, which does binary output of numbers and strings. Link in my sig
    Umm, you seem to do it totally different to me.

  4. #4
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Decimal to Binary - Optimising

    Indeed... I'm not sure how adaptable my function is to .NET but the concept is there. Maybe you might be able to optimise yours based on mine

  5. #5

    Thread Starter
    Fanatic Member x-ice's Avatar
    Join Date
    Mar 2004
    Location
    UK
    Posts
    671

    Re: Decimal to Binary - Optimising

    Quote Originally Posted by penagate
    Indeed... I'm not sure how adaptable my function is to .NET but the concept is there. Maybe you might be able to optimise yours based on mine
    If you know anything about vb.net, does my error handling look like it is in the correct place?

  6. #6
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Decimal to Binary - Optimising

    I don't think you need any error handling at all actually.

  7. #7

    Thread Starter
    Fanatic Member x-ice's Avatar
    Join Date
    Mar 2004
    Location
    UK
    Posts
    671

    Re: Decimal to Binary - Optimising

    Quote Originally Posted by penagate
    I don't think you need any error handling at all actually.
    Yeh, looking at it now, its kind of error prove.

    I was wondering if it would make much difference if i decreased the size (changed it to int16 perhaps) of the array, because i dont need all the space provided by int32. Will this small change make the function faster or save memory?
    Last edited by x-ice; Jul 21st, 2005 at 09:24 AM.

  8. #8
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Decimal to Binary - Optimising

    How much faster do you need? To optimize, you need to make the maths easier to use and also get rid of most of the string handling and use a byte array instead (though I don't know speed stuff on VB.NET).

    One thing would be to get rid of ^. It is very slow to call.
    Last edited by Merri; Jul 21st, 2005 at 10:04 AM.

  9. #9

    Thread Starter
    Fanatic Member x-ice's Avatar
    Join Date
    Mar 2004
    Location
    UK
    Posts
    671

    Re: Decimal to Binary - Optimising

    Quote Originally Posted by Merri
    How much faster do you need? To optimize, you need to make the maths easier to use and also get rid of most of the string handling and use a byte array instead (though I don't know speed stuff on VB.NET).

    One thing would be to get rid of ^. It is very slow to call.
    I'm not using ^ as a mathematical operator, i'm using it in a string, just for display purposes (see image for example). How can i make the maths easier to use? I cant get rid of the string handling stuff, i need it.

    I have changed the array to a byte array, but when i enter any number above 255 i get an overflow. This is a problem because i want the user to be able to convert any number to binary.

    p.s. i dont need it to be faster, its very fast already.
    Attached Images Attached Images  
    Last edited by x-ice; Jul 21st, 2005 at 10:18 AM.

  10. #10
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Decimal to Binary - Optimising

    Might be, they've probably improved the string handling in VB.NET a whole lot. I confused the ^ operator from penagate's code. Anyways, here is a fast VB6 alternative if you're interested to see an alternative method (commented code so you should be able to follow along):

    VB Code:
    1. Option Explicit
    2.  
    3. Public Function LongToBin(ByVal Value As Long, Optional ByVal Bits As Byte = 32) As String
    4.     Static tmpArr() As Byte
    5.     Dim A As Long, B As Long, C As Long
    6.     ' wanted no bits, return nothing
    7.     If Bits = 0 Then Exit Function
    8.     ' can return only 32 bits
    9.     If Bits > 32 Then Bits = 32
    10.     ' count where we are
    11.     A = Bits + Bits
    12.     ' reserve enough memory (VB strings are Unicode/BSTR)
    13.     ReDim Preserve tmpArr(A - 1)
    14.     ' see if we need upper byte at all...
    15.     If Bits = 32 Then
    16.         ' highest bit can not be active if value is zero or above
    17.         If Value >= 0 Then
    18.             tmpArr(0) = 48
    19.         Else
    20.             tmpArr(0) = 49
    21.         End If
    22.         ' always the same...
    23.         C = 2
    24.         B = &H40000000
    25.     Else
    26.         ' starting position in the byte array
    27.         C = 0
    28.         ' with hex values we set the upper most bit position
    29.         Select Case Bits
    30.             Case 31
    31.                 B = &H40000000
    32.             Case 30
    33.                 B = &H20000000
    34.             Case 29
    35.                 B = &H10000000
    36.             Case 28
    37.                 B = &H8000000
    38.             Case 27
    39.                 B = &H4000000
    40.             Case 26
    41.                 B = &H2000000
    42.             Case 25
    43.                 B = &H1000000
    44.             Case 24
    45.                 B = &H800000
    46.             Case 23
    47.                 B = &H400000
    48.             Case 22
    49.                 B = &H200000
    50.             Case 21
    51.                 B = &H100000
    52.             Case 20
    53.                 B = &H80000
    54.             Case 19
    55.                 B = &H40000
    56.             Case 18
    57.                 B = &H20000
    58.             Case 17
    59.                 B = &H10000
    60.             Case 16
    61.                 B = &H8000
    62.             Case 15
    63.                 B = &H4000
    64.             Case 14
    65.                 B = &H2000
    66.             Case 13
    67.                 B = &H1000
    68.             Case 12
    69.                 B = &H800
    70.             Case 11
    71.                 B = &H400
    72.             Case 10
    73.                 B = &H200
    74.             Case 9
    75.                 B = &H100
    76.             Case 8
    77.                 B = &H80
    78.             Case 7
    79.                 B = &H40
    80.             Case 6
    81.                 B = &H20
    82.             Case 5
    83.                 B = &H10
    84.             Case 4
    85.                 B = &H8
    86.             Case 3
    87.                 B = &H4
    88.             Case 2
    89.                 B = &H2
    90.             Case 1
    91.                 B = &H1
    92.         End Select
    93.     End If
    94.     ' here all the work is done!
    95.     Do
    96.         ' check if the bit is active and set character to be
    97.         ' 48 = "0" or 49 = "1" (And limits to the active byte only)
    98.         tmpArr(C) = ((Value And B) \ B) Or 48
    99.         ' check if we need to exit
    100.         If B = 1 Then Exit Do
    101.         ' to the next character in the array...
    102.         C = C + 2
    103.         ' to the next bit
    104.         B = B \ 2
    105.     Loop
    106.     ' convert byte array to string and return the value
    107.     LongToBin = CStr(tmpArr)
    108. End Function
    Last edited by Merri; Jul 21st, 2005 at 05:29 PM.

  11. #11

    Thread Starter
    Fanatic Member x-ice's Avatar
    Join Date
    Mar 2004
    Location
    UK
    Posts
    671

    Re: Decimal to Binary - Optimising

    Ok thx, instead of changing my whole code i think i'll stick with an integer array.

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Decimal to Binary - Optimising

    You'd need to add a bit to get the display you want but here's the most succinct conversion routine I think there is:
    VB Code:
    1. Public Function Dec2Bin(ByVal decNum As Integer) As String
    2.         Dim binNum As String = String.Empty
    3.  
    4.         Do
    5.             binNum = (decNum Mod 2).ToString() & binNum
    6.             decNum = decNum \ 2
    7.         Loop While decNum > 0
    8.  
    9.         Return binNum
    10.     End Function
    Edit:
    This for non-negative integers only. It would need a bit of extra work for negatives, either using absolute values or some two's complement calcs.
    Last edited by jmcilhinney; Aug 1st, 2005 at 01:47 AM.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  13. #13
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    Re: Decimal to Binary - Optimising

    Following JMC's lead I thought it would be fun to do it in C#.

    The code is longer but its actually about 5 times faster. No concatenation, no floating point operations. I have used uint's instead of int32's because there is no requirement for converting negative numbers and the largest number containable is twice as large.

    I know its in C# but that's the idea, C# lets you use pointers and unmanaged arrays and stuf like that. I just benchmarked this and it runs 1,000,000 (1 million) times in an average time of 0.66 seconds on my old, slow P4 1.8ghz PC.

    Whoooooosh! I can't get it to go any faster at the moment, if anyone knows a quicker way then let me know.

    PHP Code:
    public static unsafe string ToBinary(uint val)
    {
        
    sbytebin stackalloc sbyte[32]; //32 bytes
        
    sbyteindex bin//duplicate the array pointer and use this as the iterator
        
    sbytestop bin 32//stop after 32 bytes in the array

        
    uint mask 0x80000000//bit mask

        
    do
        {
            if((
    val mask) != 0)
                *
    index =  (sbyte)0x31
            else
                *
    index =  (sbyte)0x30

            
    mask >>= 1;
        } while(++
    index != stop); //let the index catch up the buffer one and then stop

        
    index bin//reset pointer
        
    for(mask 0mask 32 mask++)
            if(*(
    index++) == 0x31)
                break;

        return new 
    string(bin, (int)mask, (int)(32 mask));

    Last edited by wossname; Aug 25th, 2005 at 10:12 AM.
    I don't live here any more.

  14. #14
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: Decimal to Binary - Optimising

    Yeah the first thing I noticed about Wossy's code is that he straight away went for stack allocations.

    The standard VB6 code uses two heap allocations just to set up the array. You should probably use SafeArrayCreateVectorEx to reduce this to just one heap allocation (heap allocations are expensive)

    There are some (advanced) techniques to get VB to allocate safe array memory on the stack but I won't go into them here (unless you really really want me to)
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  15. #15
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    Re: Decimal to Binary - Optimising

    I'll just mention here that these samples of code are exactly equivalent in speed terms...

    1.
    Code:
            if((val & mask) != 0) 
                *index =  (sbyte)0x31; 
            else 
                *index =  (sbyte)0x30;
    2.
    Code:
            *index = (val & mask) != 0 ? (sbyte)0x31 : (sbyte)0x30;
    I used the first because its easier to read but otherwise the performance is identical and I think they probably compile to the same IL code anyway.

    I mention this because of the common misconception (stemming from VB6) that inline ?: operators are slower than if() else blocks. In C# this is not true, as demonstrated above, but in VB6 an IIf() was substancially slower than an if...end if block.

    Just FYI
    I don't live here any more.

  16. #16
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: Decimal to Binary - Optimising

    Quote Originally Posted by wossname
    I mention this because of the common misconception (stemming from VB6) that inline ?: operators are slower than if() else blocks. In C# this is not true, as demonstrated above, but in VB6 an IIf() was substancially slower than an if...end if block.
    In VB6 the IIF function is most definately slower than IF, ELSE blocks because VB processes both conclusions (the true, and the false one) and then returns the one it should (this is also a cause of some really weird errors) You should avoid the IIF function if you are using VB6. in C/C++/C# it works, as you say, just fine.
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  17. #17
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Decimal to Binary - Optimising

    I think I am right in saying, in C# the ?: operator is straight logical operation which expands to the If/Elseif, whereas VB6's IIf() function is a double expression evaluation, and a function on top of all that.

  18. #18
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Decimal to Binary - Optimising

    I see we agree on that point

  19. #19
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253

    Re: Decimal to Binary - Optimising

    Of course
    "As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

    It's turtles! And it's all the way down

  20. #20
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    Re: Decimal to Binary - Optimising

    Natch.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width