Помните, что вы получаете дополнение к одному прямо сейчас с помощью ~, если вы передаете Fixnum: число битов, представляющих число, является фиксированной величиной в интерпретаторе, и, таким образом, перед двоичным представлением перед нулями стоят первые 0. число 9 (двоичное 1001). Вы можете найти это количество бит, изучив размер любого Fixnum. (ответ возвращается в байтах)
1.size #=> 4
2147483647.size #=> 4
~ также определяется над Bignum. В этом случае он ведет себя так, как если бы все биты, указанные в Bignum, были инвертированы, а затем, если перед этим Bignum была бесконечная строка из 1. Вы можете, возможно, засунуть свой поток битов в Bignum и инвертировать все это. Однако вам потребуется знать размер потока битов до инверсии, чтобы получить полезный результат после его инвертирования.
Чтобы ответить на вопрос, задав его сразу, вы можете найти наибольшую степень 2, меньшую, чем ваш вход, удвоить ее, вычесть 1, затем XOR результат этого с вашим входом и всегда получить единичные дополнения. только значащие биты в вашем входном номере.
def sig_ones_complement(num)
significant_bits = num.to_s(2).length
next_smallest_pow_2 = 2**(significant_bits-1)
xor_mask = (2*next_smallest_pow_2)-1
return num ^ xor_mask
end