Testing if an integer is an uppercase ASCII letter using bit manipulation

后端 未结 4 789
南方客
南方客 2021-01-28 11:35

For an assignment, I\'m trying to make some code in C that uses only bit manipulation to test if an integer is an ASCII uppercase letter. The letter will be given by its ASCII c

4条回答
  •  没有蜡笔的小新
    2021-01-28 12:28

    You could use unsigned integer division, if that's allowed:

    !((x-0x41)/26)
    

    But that's probably not in the spirit of the original question. Consider what happens when you subtract 0x3B from any upper case letter:

    A: 0x41 - 0x3B = 0x06
    Z: 0x5A - 0x3B = 0x1F
    

    The interesting feature here is that any value initially larger than 0x5A will have one of the high bits set (~0x1F). You can perform the same shifting for moving 'A' down to zero, so anything initially less than 'A' would have the high bits set. In the end a solution requires only subtractions, an or, and some bit-wise ands:

    !(((x-0x3B) & ~(0x1F)) || ((x-0x41) & ~(0x1F)))
    

    I believe that does what you want. Given the nature of conditional (short circuit) evaluation in C, this has an implicit conditional embedded in it though. If you want to remove that, minimize the computation, and maximize the obscurity you could do this:

    !(((x-0x3B) | (x-0x41)) & ~(0x1F))
    

    or my new personal favorite:

    !((('Z'-x) | (x-'A')) & ~(0x1F))
    

提交回复
热议问题