所以我想获得我的基础ruby技能(来自python背景),因为我想在轨道上得到很好的处理。
我正在做一些我自己选择的练习,并且出现了这个特殊的错误(这不是一个错误,但我正在挑起眉毛) - 为了它的价值,我正在使用ruby 2.0.0
Class A
def B(binaryNum)
puts binaryNum
binarray = binaryNum.to_s.chars.to_a
indice = binarray.length
puts "\n#{indice}"
end
end
conv = A.new()
puts "#{conv.B(1111)}" # outputs 1111 as usual, with a length of 4
puts "#{conv.B(01111)}" # outputs 585, with a length of 3
似乎在二进制的整数表示之前放置零会导致各种各样的骚扰发生。我最初认为这可能是关于最大值的愚蠢错误,但我用更小的数字再现了这个问题。
答案 0 :(得分:2)
Ruby的数值语法与C类似,前导零使其将数字解释为八进制(基数为8)。
1111 base 8 = 585 base 10.
答案 1 :(得分:1)
Ruby中带有前导零的数字文字被视为八进制数。
根据ruby-doc.org documentation for numeric literals:
您可以使用特殊前缀来写入十进制,十六进制的数字, 八进制或二进制格式。对于十进制数字,使用前缀0d,for 十六进制数字使用前缀0x,表示八进制数字使用前缀 为0或0o ,对于二进制数,使用前缀0b。字母 数字的组成部分不区分大小写。
示例:
0d170 0D170 0xaa 0xAa 0xAA 0Xaa 0XAa 0XaA 0252 0o252 0O252 0b10101010 0B10101010
因此,在您的情况下,由于1111 8 = 585 10 ,01111.to_s
将返回"585"
。
请注意Fixnum#to_s
采用一个参数,可以指定您正在使用的数字系统的基数。所以对于你的程序,你可以这样做:
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
更好的是,在Ruby 2.1+ Fixnum
中有一个名为bit_length
的实例方法,它似乎已经做了你想做的事情:
0b1.bit_length
#=> 1
0b11.bit_length
#=> 2
0b111.bit_length
#=> 3
0x1FF.bit_length
#=> 9