0

I have function to transcode input hexadecimal number. For example I have initial format of number like this

Initial format

And function transcodes it to this format:

Final format

I will return result from function as a string using hex built-in function. I tried something like this, but that didn't work:

def task22(number) -> str:
    """
    Returns transcoded hexadecimal string, this function uses bitwise operators to transcode given value
    :param number: hexadecimal number to transcode
    :return: Transcoded hexadecimal string
    """
    a = number & 0b111111111111111
    b = number & 0b111111111111111
    c = number & 0b11
    a = a << 17
    b = b >> 13
    c = c >> 30

    return hex(a | b | c)

How can I use bitwise operators to transcode number? I need to use bitwise shifts to the left and right but I have no idea how to do it for formats described above.

WideWood
  • 549
  • 5
  • 13
  • 1
    For each segment, take the difference of the bit number where you started and the bit number where you want to end up. If it's positive, shift right by that many bits. If it's negative, shift left by the negative of the difference. – Mark Ransom Mar 10 '21 at 00:39
  • I tried. In the first case A begins from 0 and ends on 14 so it is 15 bits, C is 2 bits because that begins from 30 and ends on 31 B is 15 bits. I swap A and C. I need to shift A to the right by 17 bits because B + C aka 15 + 2 = 17 and C to the left by 30 bits because A + B aka 15 + 15 = 30. Is that right? – WideWood Mar 10 '21 at 01:05
  • 2
    No, that's not what I meant. Pick just one end, doesn't matter which one. A starts at 0, and you want to move it to 17, so the difference is -17 - you want to left shift by 17. – Mark Ransom Mar 10 '21 at 01:15
  • Yep. `((number & 0x7ffff) << 17) | ((number & 0x3fff8) >> 13) | ((number & 0xc0000000) >> 30)`. – Tim Roberts Mar 10 '21 at 01:29
  • Ok I shifted it. Now I want to right shift C by 30 because it starts at 30 and I want to shit it to 0 so the difference is 30. Also I changed my code in question. Well I guess I need shift B segment to get final value, it starts at 15 and I want to shift it to 2 so the difference is 13, but I get wrong value, first three digits are right but others all are zeros. – WideWood Mar 10 '21 at 01:30
  • I passed 0x2ec492c8 to function and that returned 0x25900000 but result must be 0x25917624. – WideWood Mar 10 '21 at 01:40
  • Your `a` and `b` are equal - clearly you are not extracting the parts of the number you think you are. – kaya3 Mar 10 '21 at 03:47

1 Answers1

0

Solved. The problem was I needed to process all segments using bitwise AND operator with 32 zeros (because number of all bits is 32) replaced by 1 where each segment is located in the sequence of bits like this:

def task22(number) -> str:
    """
    Returns transcoded hexadecimal string, this function uses bitwise operators to transcode given value
    :param number: hexadecimal number to transcode
    :return: Transcoded hexadecimal string
    """
    a = number & 0b00000000000000000111111111111111
    b = number & 0b00111111111111111000000000000000
    c = number & 0b11000000000000000000000000000000
    a = a << 17
    b = b >> 13
    c = c >> 30

    return hex(a | b | c)
WideWood
  • 549
  • 5
  • 13