Flipping bits without getting negative number - ruby

How can I flip the bits of an integer without changing its sign? For example, how can I flip "1010" (1010) to "0101" (510)?
Bitwise negative operator results in negative number: ~10 (~0b1010) → -11 (0b0101).

You can flip the bits via XOR:
1010 (decimal 10)
XOR 1111 (decimal 15)
= 0101 (decimal 5)
In Ruby:
0b1010 ^ 0b1111 #=> 5
The number of 1's corresponds to the number of bits, therefore you could use:
num = 0b1010
num ^ (1 << num.bit_length) - 1
#=> 5

If you mean strings, then:
"1010".tr("01", "10") # => "0101"
If you mean numbers, then:
10.to_s(2).tr("01", "10").to_i(2) # => 5

I am not sure if it fits for your needs, but you can just flip binary string char by char like this:
"1010".chars.map { |i| i == "1" ? "0" : "1" }.join #=> "0101"
Upd:
How about this:
a = ~10
(a.bit_length - 1).downto(0).map { |i| a[i] }.join #=> "0101"

Related

CRC Polynomial Division

I am trying to use polynomial division to find the CRC check bits, but I am struggling with the last stage of the calculation.
I am believe the below conversions are correct:
Pattern = 1010
= x^3 + x
Dataword = 9 8 7
= 1001 1000 0111
= x^11 + x^8 + x^7 + x^2 + x + 1
And finally the polynomial long division I am attempted is:
x^8 + x^6 + x^5 + x^3 + x
_______________________________________
x^3 + x | x^11 + x^8 + x^7 + x^2 + x + 1
x^11 + x^9
....
x^4 + x^2 + x + 1
x^4 + x^2
= x + 1
My question is, is the remainder / answer x + 1 or do I take it a step further and remove the x leaving the remainder as just 1?
Thank you for your help!
We can check by mod 2 division (XOR) too, the following code shows a python implementation of CRC checking, we need to follow the steps listed below:
Convert CRC / data polynomials to corresponding binary equivalents.
if the CRC key (binary representation obtained from the polynomial) has k bits, we need to pad an additional k-1 bits with the data to check for errors. In the example given, the bits 011 should be appended to the data, not 0011, since k=4.
At the transmitter end,
The binary data is to be augmented first by adding k-1 zeros in the end of the data.
Use modulo-2 binary division to divide binary data by the CRC key and store remainder of division.
Append the remainder at the end of the data to form the encoded data and send the same
At the receiver end (Check if there are errors introduced in transmission)
Perform modulo-2 division again on the sent data with the CRC key and if the remainder is 0, then there are no errors.
Now let's implement the above:
def CRC_polynomial_to_bin_code(pol):
return bin(eval(pol.replace('^', '**').replace('x','2')))[2:]
def get_remainder(data_bin, gen_bin):
ng = len(gen_bin)
data_bin += '0'*(ng-1)
nd = len(data_bin)
divisor = gen_bin
i = 0
remainder = ''
print('\nmod 2 division steps:')
print('divisor dividend remainder')
while i < nd:
j = i + ng - len(remainder)
if j > nd:
remainder += data_bin[i:]
break
dividend = remainder + data_bin[i:j]
remainder = ''.join(['1' if dividend[k] != gen_bin[k] else '0' for k in range(ng)])
print('{:8s} {:8s} {:8s}'.format(divisor, dividend, remainder[1:]))
remainder = remainder.lstrip('0')
i = j
return remainder.zfill(ng-1)
gen_bin = CRC_polynomial_to_bin_code('x^3+x')
data_bin = CRC_polynomial_to_bin_code('x^11 + x^8 + x^7 + x^2 + x + 1')
print('transmitter end:\n\nCRC key: {}, data: {}'.format(gen_bin, data_bin))
r = get_remainder(data_bin, gen_bin)
data_crc = data_bin + r
print('\nencoded data: {}'.format(data_crc))
print('\nreceiver end:')
r = get_remainder(data_crc, gen_bin)
print('\nremainder {}'.format(r))
if eval(r) == 0:
print('data received at the receiver end has no errors')
# ---------------------------------
# transmitter end:
#
# CRC key: 1010, data: 100110000111
#
# mod 2 division steps:
# divisor dividend remainder
# 1010 1001 011
# 1010 1110 100
# 1010 1000 010
# 1010 1000 010
# 1010 1011 001
# 1010 1100 110
# 1010 1100 110
#
# encoded data: 100110000111110
# ---------------------------------
# receiver end:
#
# mod 2 division steps:
# divisor dividend remainder
# 1010 1001 011
# 1010 1110 100
# 1010 1000 010
# 1010 1000 010
# 1010 1011 001
# 1010 1111 101
# 1010 1010 000
#
# remainder 000
# data received at the receiver end has no errors
# ---------------------------------

How to check if count of one part of the string is equal to another part with regex?

I have a strings like:
0011
01
000111
000111
I need to validate them like this: count of "0" must be identical to the count of "1". So "001" - invalid, "0011" - valid.
How can I do this with regex?
In Ruby, you can use subroutines:
m = /\b(0(\g<1>)?1)\b/.match('000111');
puts m;
Result of the demo:
000111
Or, you can just use capturing groups to match adjacent 0s and 1s, and then check the captured group length:
m = /(0+)(1+)/.match('0011');
puts m[1].length === m[2].length ? "True" : "False";
m = /(0+)(1+)/.match('00111');
puts m[1].length === m[2].length ? "True" : "False";
You may add ^ and $ to only match a string consisting of leading zeros and trailing 1s (m = /^(0+)(1+)$/.match('00111');).
Output of the demo program:
True
False

Converting a floating point to its corresponding bit-segments

Given a Ruby Float value, e.g.,
f = 12.125
I'd like to wind up a 3-element array containing the floating-point number's sign (1 bit), exponent (11 bits), and fraction (52 bits). (Ruby's floats are the IEEE 754 double-precision 64-bit representation.)
What's the best way to do that? Bit-level manipulation doesn't seem to be Ruby's strong point.
Note that I want the bits, not the numerical values they correspond to. For instance, getting [0, -127, 1] for the floating-point value of 1.0 is not what I'm after -- I want the actual bits in string form or an equivalent representation, like ["0", "0ff", "000 0000 0000"].
The bit data can be exposed via Arrays pack as Float doesn't provide functions internally.
str = [12.125].pack('D').bytes.reverse.map{|n| "%08b" %n }.join
=> "0100000000101000010000000000000000000000000000000000000000000000"
[ str[0], str[1..11], str[12..63] ]
=> ["0", "10000000010", "1000010000000000000000000000000000000000000000000000"]
This is a bit 'around about the houses' to pull it out from a string representation. I'm sure there is a more efficient way to pull the data from the original bytes...
Edit The bit level manipulation tweaked my interest so I had a poke around. To use the operations in Ruby you need to have an Integer so the float requires some more unpacking to convert into a 64 bit int. The big endian/ieee754 documented representation is fairly trivial. The little endian representation I'm not so sure about. It's a little odd, as you are not on complete byte boundaries with an 11 bit exponent and 52 bit mantissa. It's becomes fiddly to pull the bits out and swap them about to get what resembles little endian, and not sure if it's right as I haven't seen any reference to the layout. So the 64 bit value is little endian, I'm not too sure how that applies to the components of the 64bit value until you store them somewhere else, like a 16bit int for the mantissa.
As an example for an 11 bit value from little > big, The kind of thing I was doing was to shift the most significant byte left 3 to the front, then OR with the least significant 3 bits.
v = 0x4F2
((v & 0xFF) << 3) | ( v >> 8 ))
Here it is anyway, hopefully its of some use.
class Float
Float::LITTLE_ENDIAN = [1.0].pack("E") == [1.0].pack("D")
# Returns a sign, exponent and mantissa as integers
def ieee745_binary64
# Build a big end int representation so we can use bit operations
tb = [self].pack('D').unpack('Q>').first
# Check what we are
if Float::LITTLE_ENDIAN
ieee745_binary64_little_endian tb
else
ieee745_binary64_big_endian tb
end
end
# Force a little end calc
def ieee745_binary64_little
ieee745_binary64_little_endian [self].pack('E').unpack('Q>').first
end
# Force a big end calc
def ieee745_binary64_big
ieee745_binary64_big_endian [self].pack('G').unpack('Q>').first
end
# Little
def ieee745_binary64_little_endian big_end_int
#puts "big #{big_end_int.to_s(2)}"
sign = ( big_end_int & 0x80 ) >> 7
exp_a = ( big_end_int & 0x7F ) << 1 # get the last 7 bits, make it more significant
exp_b = ( big_end_int & 0x8000 ) >> 15 # get the 9th bit, to fill the sign gap
exp_c = ( big_end_int & 0x7000 ) >> 4 # get the 10-12th bit to stick on the front
exponent = exp_a | exp_b | exp_c
mant_a = ( big_end_int & 0xFFFFFFFFFFFF0000 ) >> 12 # F000 was taken above
mant_b = ( big_end_int & 0x0000000000000F00 ) >> 8 # F00 was left over
mantissa = mant_a | mant_b
[ sign, exponent, mantissa ]
end
# Big
def ieee745_binary64_big_endian big_end_int
sign = ( big_end_int & 0x8000000000000000 ) >> 63
exponent = ( big_end_int & 0x7FF0000000000000 ) >> 52
mantissa = ( big_end_int & 0x000FFFFFFFFFFFFF ) >> 0
[ sign, exponent, mantissa ]
end
end
and testing...
def printer val, vals
printf "%-15s sign|%01b|\n", val, vals[0]
printf " hex e|%3x| m|%013x|\n", vals[1], vals[2]
printf " bin e|%011b| m|%052b|\n\n", vals[1], vals[2]
end
floats = [ 12.125, -12.125, 1.0/3, -1.0/3, 1.0, -1.0, 1.131313131313, -1.131313131313 ]
floats.each do |v|
printer v, v.ieee745_binary64
printer v, v.ieee745_binary64_big
end
TIL my brain is big endian! You'll note the ints being worked with are both big endian. I failed at bit shifting the other way.
Use frexp from the Math module. From the doc:
fraction, exponent = Math.frexp(1234) #=> [0.6025390625, 11]
fraction * 2**exponent #=> 1234.0
The sign bit is easy to find on its own.

How to convert a signed int to its hex representation on nbBits, in Ruby?

For instance : -78_base10 on 8 bits is 0xB2
The pseudo-algorithm says : "-A =/A+1"
For instance :
-78 => 78 => 01001110
Then apply 'bar' : 01001110 => 10110001
Then '+1' : 10110001 + 1 = 10110010
convert in hexa : 0xB2
How to get the result nicely in Ruby (with or without this 'algorithm').
How about something like
def signed_int_to_hex(n)
"0x%X" % (n % 2 ** 8)
end
signed_int_to_hex(-78) #=> "0xB2"
((-78) % 2 ** 8).to_s(16)
# => "b2"

What is a good way to iterate a number through all the possible values of a mask?

Given a bitmask where the set bits describe where another number can be one or zero and the unset bits must be zero in that number. What's a good way to iterate through all its possible values?
For example:
000 returns [000]
001 returns [000, 001]
010 returns [000, 010]
011 returns [000, 001, 010, 011]
100 returns [000, 100]
101 returns [000, 001, 100, 101]
110 returns [000, 010, 100, 110]
111 returns [000, 001, 010, 011, 100, 101, 110, 111]
The simplest way to do it would be to do it like this:
void f (int m) {
int i;
for (i = 0; i <= m; i++) {
if (i == i & m)
printf("%d\n", i);
}
}
But this iterates through too many numbers. It should be on the order of 32 not 2**32.
There's a bit-twiddling trick for this (it's described in detail in Knuth's "The Art of Computer Programming" volume 4A §7.1.3; see p.150):
Given a mask mask and the current combination bits, you can generate the next combination with
bits = (bits - mask) & mask
...start at 0 and keep going until you get back to 0. (Use an unsigned integer type for portability; this won't work properly with signed integers on non-two's-complement machines. An unsigned integer is a better choice for a value being treated as a set of bits anyway.)
Example in C:
#include <stdio.h>
static void test(unsigned int mask)
{
unsigned int bits = 0;
printf("Testing %u:", mask);
do {
printf(" %u", bits);
bits = (bits - mask) & mask;
} while (bits != 0);
printf("\n");
}
int main(void)
{
unsigned int n;
for (n = 0; n < 8; n++)
test(n);
return 0;
}
which gives:
Testing 0: 0
Testing 1: 0 1
Testing 2: 0 2
Testing 3: 0 1 2 3
Testing 4: 0 4
Testing 5: 0 1 4 5
Testing 6: 0 2 4 6
Testing 7: 0 1 2 3 4 5 6 7
(...and I agree that the answer for 000 should be [000]!)
First of all, it's unclear why 000 wouldn't return [000]. Is that a mistake?
Otherwise, given a mask value "m" and number "n" which meets the criterion (n & ~m)==0, I would suggest writing a formula to compute the next higher number. One such formula uses the operators "and", "or", "not", and "+", once each.
The trick by #Matthew is amazing. Here is a less tricky, but unfortunately also a less efficient, recursive version in Python:
def f(mask):
if mask == "0":
return ['0']
elif mask == '1':
return ['0', '1']
else:
bits1 = f(mask[1:])
bits2 = []
for b in bits1:
bits2.append('0' + b)
if mask[0] == '1':
bits2.append('1' + b)
return bits2
print f("101") ===> ['000', '100', '001', '101']
You can do it brute-force. ;-) Ruby example:
require 'set'
set = Set.new
(0..n).each do |x|
set << (x & n)
end
(where set is a set datatype, i.e., removes duplicates.)
Try this code:
def f (máscara):
se máscara == "0":
voltar ['0 ']
elif máscara == '1 ':
voltar ['0 ', '1']
else:
bits1 = f (máscara [1:])
bits2 = []
para b em bits1:
bits2.append ('0 '+ b)
se máscara [0] == '1 ':
bits2.append ('1 '+ b)
voltar bits2
print f ("101") ===> ['000 ', '100', '001 ', '101']
é interessante .

Resources