How to calculate one addition using bitwise Ruby operators?

What I want:

assert_equal 6, ones_complement(9)   # 1001 => 0110
assert_equal 0, ones_complement(15)  # 1111 => 0000
assert_equal 2, ones_complement(1)   # 01 => 10

input size is not fixed as in 4 bits or 8 bits. rather its binary stream.

What do I see:

v = "1001".to_i(2)                 => 9

There the operator flips a little ~

(~v).to_s(2)                       => "-1010"
sprintf("%b", ~v)                  => "..10110"
~v                                 => -10

I think this is due to the fact that one bit is used to store a character or something else ... can anyone explain this conclusion? How to get one addition without resorting to string manipulations, for example, cutting out the last n characters from sprintf output to get "0110" or replace 0 with 1 and vice versa

+3
source share
6 answers

It looks like you only want to flip four bits (the length of your input) - so you probably want XOR from 1111.

+4

Ruby () . : FixNum, BigNum - . undefined: . , , C, int, , 32 ().

, ~? , - :

class Numeric
    def ~
        return -self - 1
    end
end

... , ~ ~ , 2 .

, - , : 32- ~ ~, Ruby.

, n-, - :

class Numeric
    def ones_complement(bits)
        self ^ ((1 << bits) - 1)
    end
end

... . , XOR:)

+6

. .

, , : 1001 -> 0110.

, ~ : 00001001 -> 11110110. 1 .

, , 0b101 0b11011, , . 4 , v^0b1111, . , .

:

def maskbits n
  b=1
  prev=n;
  mask=prev|(prev>>1)
  while (mask!=prev)
    prev=mask;
    mask|=(mask>>(b*=2))
  end
  mask
end

def ones_complement n
  n^maskbits(n)
end

p ones_complement(9).to_s(2)  #>>"110" 
p ones_complement(15).to_s(2) #>>"0"
p ones_complement(1).to_s(2)  #>>"0"

one_compliment (1), 1 "1", "01". , , , .

+3

, ( ~), . , - , Ruby.

, , , . , 1 ?

0

, :

s = "0110"
s.gsub("\d") {|bit| bit=="1"?"0":"1"}

, , :
0110 = 6; 1001 = 9;
110 = 6; 001 = 1;

, , , , .

0

, ~, Fixnum: , , , 0 9 ( 1001). , Fixnum. ( )

1.size            #=> 4
2147483647.size   #=> 4

~ Bignum. , , Bignum , , 1 Bignum. , , - Bignum . , .

In order to answer this question, you put it right off the bat, you can find the greatest power 2 less than data input, double it, subtract 1, then XOR is the result of the fact that with your input you always get one complement only significant bits in your input number.

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
0
source

Source: https://habr.com/ru/post/1713879/


All Articles