我正在开发一个代码战kata并且遇到了2个失败的测试用例。
kata说明是: 将整数转换为二进制就像那样简单。您将获得一个整数作为参数,您必须返回其二进制形式。要了解如何将十进制数转换为二进制数,请访问此处。
注意:负数应作为二进制补码处理;假设所有数字都是使用任何语言的4个字节(或32位)存储的整数。
我的代码:
def to_binary(n)
temp_array = []
if n == 0
temp_array << 0
elsif n < 0
n = n % 256
while n > 0 do
temp_array << (n % 2)
n = (n / 2)
end
while temp_array.length < 32 do
temp_array << 1
end
else
while n > 0 do
temp_array << (n % 2)
n = (n / 2)
end
end
binary = temp_array.reverse.join
end
测试用例是:
Test Passed: Value == "10"
Test Passed: Value == "11"
Test Passed: Value == "100"
Test Passed: Value == "101"
Test Passed: Value == "111"
Test Passed: Value == "1010"
Test Passed: Value == "11111111111111111111111111111101"
Test Passed: Value == "0"
Test Passed: Value == "1111101000"
Test Passed: Value == "11111111111111111111111111110001"
Expected: "11111111111111111111110000011000", instead got: "11111111111111111111111111111000"
Expected: "11111111111100001011110111000001", instead got: "11111111111111111111111111000001"
Test Passed: Value == "11110100001000111111"
我怀疑失败的测试是负整数,因为第一个失败测试的预期输出是11111111111111111111110000011000
,这意味着正参数值为4294966296
或者为负。如果我运行to_binary(4294966296)
,我会得到预期的输出。
答案 0 :(得分:7)
我并不喜欢这种方法,因为我确信这是一种更加聪明和/或紧凑的Ruby式方式来实现它。但是使用你的方法将二进制数字加载到一个数组中,然后加入,你可以用一种更直接的方式完成你的工作:
def to_binary(n)
return "0" if n == 0
r = []
32.times do
if (n & (1 << 31)) != 0
r << 1
else
(r << 0) if r.size > 0
end
n <<= 1
end
r.join
end
或者,使用@ 500_error的建议:
def to_binary(n)
if n >= 0
n.to_s(2)
else
31.downto(0).map { |b| n[b] }.join
end
end
但是,处理消极与非消极的不对称有点令人讨厌。你可以这样做:
def to_binary(n)
31.downto(0).map { |b| n[b] }.join.sub(/^0*/, "")
end
答案 1 :(得分:1)
这不是生成2的补码的传统算法,所以我不确定它是否有助于你理解二进制转换,但你可以用红宝石来帮助检查你的答案。
注意:这仅适用于负数。
32.downto(0).map { |n| -4294966296[n] }.join
=> "100000000000000000000001111101000"
对于2的补码计算,最好使用像C这样的低级语言来实现,以了解算法。聪明的方法掩盖了步骤,只是给你一个答案。
假设我们正在使用8位(为简单起见),并假设我们想要找到-28将如何以二进制补码表示法表示。
首先我们以二进制形式写出28。 00011100
然后我们反转数字。 0变为1,1变为0。 11100011
然后我们加1。 11100100