3

I want to create new method Integer#to_bin that convert decimal to a binary string. The argument of #to_bin is the number of digits. The result should be padded with leading zeros to make it have that many digits.

Example:

1.to_bin(4)
#=> "0001"
1.to_bin(3)
#=> "001"
1.to_bin(2)
#=> "01"
7.to_bin(1)
#=> nil
7.to_bin
#=> "111"
etс.

What I've tried:

class Integer

    def to_bin(number=nil)
        if number == nil
          return self.to_s(2)
        else 
          s = self.to_s(2).size
          e = number-s
          one = '0'
          two = '00'
          three = '000'

        if e==one.size
          one+self.to_s(2)
        elsif e==two.size
          two+self.to_s(2)
        elsif e==three.size
          three+self.to_s(2)
        end
        end
    end
end

How do I convert an integer to a binary string padded with leading zeros?

6
  • 1
    Sorry, what are you trying to do? Commented Jul 3, 2013 at 7:55
  • convert decimal to binary Commented Jul 3, 2013 at 8:00
  • Doesn't to_s(2) work? Commented Jul 3, 2013 at 8:01
  • No, you're not trying to convert decima; to bin, you try to do some black magic. I'm asking what is that exactly. (to convert dec to bin to_s(2) is enough) Commented Jul 3, 2013 at 8:02
  • i want to add left-pad it with zeroes Commented Jul 3, 2013 at 8:08

2 Answers 2

35

The appropriate way to do this is to use Kernel's sprintf formatting:

'%03b' % 1 # => "001"
'%03b' % 2 # => "010"
'%03b' % 7 # => "111"

'%08b' % 1 # => "00000001"
'%08b' % 2 # => "00000010"
'%08b' % 7 # => "00000111"

But wait, there's more!:

'%0*b' % [3, 1] # => "001"
'%0*b' % [3, 2] # => "010"
'%0*b' % [3, 7] # => "111"

'%0*b' % [8, 1] # => "00000001"
'%0*b' % [8, 2] # => "00000010"
'%0*b' % [8, 7] # => "00000111"

So defining a method to extend Fixnum or Integer is easy and cleanly done:

class Integer
  def to_bin(width)
    '%0*b' % [width, self]
  end
end

1.to_bin(8) # => "00000001"
0x55.to_bin(8) # => "01010101"
0xaaa.to_bin(16) # => "0000101010101010"
Sign up to request clarification or add additional context in comments.

Comments

16

Ruby already has a built-in mechanism to convert a number to binary: #to_s accepts a base to convert to.

30.to_s(2) # => "11110"

If you want to left-pad it with zeroes:

30.to_s(2).rjust(10, "0") => "0000011110"

You could extend this into a little method that combines the two:

class Fixnum
  def to_bin(width = 1)
    to_s(2).rjust(width, "0")
  end
end

> 1234.to_bin
=> "10011010010"
> 1234.to_bin(20)
=> "00000000010011010010"

5 Comments

String#rjust would be a little cleaner - 30.to_s(2).rjust(10, "0")
Ah, good point. I was looking for #format since I knew there was some way to right-justify with the string as the receiver!
This does not give nil to 7.to_bin(1).
I presumed that was a bug, since it wasn't actually specified in the requirements as far as I can tell.
It looks like the expected behavior is to return nil when the argument is given and is less than the string length in binary before padding. In addition, the OPs code returns nil when the argument is other than 1, 2, or 3. I am not sure whether that was intended. But the question is badly phrased. It is mostly the OP's fault.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.