Why Is 032 Different Than 32 in Ruby

Why is 032 different than 32 in Ruby?

What you're seeing is 032 is an octal representation, and 32 is decimal:

>> 032 #=> 26
>> 32 #=> 32
>> "32".to_i(8) #=> 26
>> "32".to_i(10) #=> 32

And, just for completeness, you might need to deal with hexadecimal:

>> 0x32 #=> 50
>> "32".to_i(16) #=> 50

and binary:

>> 0b100000 #=> 32
>> 32.to_s(2) #=> "100000"

Placing zeros as first number causes odd results

Numeric literals with leading zeros in Ruby are treated as octal numbers.

According to the ruby-doc.org documentation for numeric literals:

You can use a special prefix to write numbers in decimal, hexadecimal,
octal or binary formats. For decimal numbers use a prefix of 0d, for
hexadecimal numbers use a prefix of 0x, for octal numbers use a prefix
of 0 or 0o
, for binary numbers use a prefix of 0b. The alphabetic
component of the number is not case-sensitive.

Examples:

0d170
0D170

0xaa
0xAa
0xAA
0Xaa
0XAa
0XaA

0252
0o252
0O252

0b10101010
0B10101010

So in your case, since 11118 = 58510, 01111.to_s will return "585".


Note that Fixnum#to_s takes an argument which lets you specifiy the base of the number system you are using. So for your program, you could do it like this:

class A
def B(binaryNum)
puts binaryNum
binarray = binaryNum.to_s(2).chars.to_a
indice = binarray.length
puts "\n#{indice}"
end
end

conv = A.new
puts "#{conv.B(0b1111)}" # Outputs 15, with a length of 4
puts "#{conv.B(01111)}" # Outputs 585, with a length of 10
puts "#{conv.B(1111)}" # Outputs 1111, with a length of 11

Even better, in Ruby 2.1+ Fixnum has an instance method called bit_length which seems to already do what you want:

0b1.bit_length
#=> 1
0b11.bit_length
#=> 2
0b111.bit_length
#=> 3
0x1FF.bit_length
#=> 9

What is an Illegal octal digit?

Ruby is interpreting numbers that have a leading 0 as being in octal (base 8). Thus the digits 8 and 9 are not valid.

It probably makes more sense to store ZIP codes as strings, instead of as numbers (to avoid having to pad with zeroes whenever you display it), as such: array = ["07001", "07920"]

Difference between '..' (double-dot) and '...' (triple-dot) in range generation?

The documentation for Range says this:

Ranges constructed using .. run from the beginning to the end inclusively. Those created using ... exclude the end value.

So a..b is like a <= x <= b, whereas a...b is like a <= x < b.


Note that, while to_a on a Range of integers gives a collection of integers, a Range is not a set of values, but simply a pair of start/end values:

(1..5).include?(5)           #=> true
(1...5).include?(5) #=> false

(1..4).include?(4.1) #=> false
(1...5).include?(4.1) #=> true
(1..4).to_a == (1...5).to_a #=> true
(1..4) == (1...5) #=> false



The docs used to not include this, instead requiring reading the Pickaxe’s section on Ranges. Thanks to @MarkAmery (see below) for noting this update.

Ruby float to Binary32

The above is awesome but I have a few simplifications:

[123.456].pack('g').bytes.map{|n| "%08b" % n}.join

Using the 'g' flag instead of 'e' avoids having to reverse the output from pack.
The bytes method does the same thing as calling .ord on each character does.
Then instead of taking the 4 integers and doing the sum/bit shift you map each to an 8 character binary string and join them together.

Throws wrong number of arguments error

In Rails 4 where.not is introduced. You are working on Rails 3.2.13, so you have to do something like this:

 Subscription.where('valid_until IS NULL and activated_on IS NOT NULL')

Local variables for a class in ruby

The body of a class in Ruby is just executable Ruby code. These are indeed local variables (no quotation needed) and follow the "regular" rules being local variables. You can access them in the body of the class. If you literally want the scope where bar is defined, you can use Kernel.binding:

class Foo
bar = 42

@@scope = binding

def self.scope
@@scope
end
end

Foo.scope.local_variables # => [:bar]
Foo.scope.local_variable_get(:bar) # => 42

A thing to note - using def changes the scope, therefore, they won't be visible inside methods defined using def.

Hash#stringify_keys undefined

Rails (via ActiveSupport) monkey patches the stringify_keys method into Hash so you won't have it in a plain irb session. You can load the core extensions by saying:

require 'active_support/core_ext'

See the Active Support Core Extensions Guide for details on loading individual monkey patches.



Related Topics



Leave a reply



Submit