将零作为第一个数字放置会导致奇怪的结果

时间:2015-01-20 19:06:15

标签: ruby

所以我想获得我的基础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

似乎在二进制的整数表示之前放置零会导致各种各样的骚扰发生。我最初认为这可能是关于最大值的愚蠢错误,但我用更小的数字再现了这个问题。

2 个答案:

答案 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