我想为一些同行做一个演示,我想强制IRB只返回二进制值。
例如,无论输入在哪个基数,它当前都会在基数10中返回结果:
0b1111
# => 15 #should return 1111 or 0b1111
0b0001 | 0b0011
# => 3 #should return 0011 or 0b0011
有没有办法强制这个结果?我想演示按位运算符,他们更容易理解,如果他们看到流出的位而不是返回的基数为10,那么之后我将不得不转换为基数2.
此外,我希望所有结果都是4位的倍数。如果可能,使用下划线或空格分隔半字节分组。
例如:
0b0001_0101
# => 0b0001_0101 #or 0b0001 0101, or 0001 0101, or 0001_0101
如果我的结果不需要用4位(例3,11)表示,则根据数字将其填充为4,8,16位。
答案 0 :(得分:1)
如果你写0b0001.class
,你会发现它是Fixnum。
撰写puts 0b1000
会显示8
,并且很清楚此Fixnum存储在基础10中。
因此,据我所知,没有任何方法可以阻止转换为10。
如果要控制Fixnum对象在IRB中的显示方式,可以为该类实现自定义inspect
方法:
class Fixnum
def inspect
unpadded_binary_string = to_s(2)
binary_width = if unpadded_binary_string.length % 4 == 0
unpadded_binary_string.length
else
((unpadded_binary_string.length / 4) * 4) + 4
end
padded_binary_string = "%0#{binary_width}d" % unpadded_binary_string
# join groups of 4 with an underscore
padded_binary_string = padded_binary_string.scan(/.{4}/).join("_")
"0b" + padded_binary_string
end
end
结果:
irb(main):007:0> 0b1000
=> 0b1000
irb(main):011:0> 99999999
=> 0b0101_1111_0101_1110_0000_1111_1111
inspect方法使用to_s(2)
,它接受一个整数并生成一个二进制的字符串表示。但是,当二进制文件转换为基数10时,二进制文件前面的零点会丢失。这就是检查方法的原因。
需要手动将零添加到字符串的前面。
我无法想象以完全动态的方式在字符串的前面添加正确数量的零。
我在这里做的是计算可以包含未填充的二进制字符串的最小宽度(以4的倍数)。因此,如果未填充长度为5个字符,则最终宽度为8.如果未填充长度为2,则最终长度为4.
您可以选择将binary_width
设置为在运行时更改的外部变量,然后从inspect函数引用它,而不是在运行中计算它。