0

I need to set all bits in a byte high if any of its bits are high. If none of them is high, all bits should be low.

So if the byte is 0000 1000 it should be set to 1111 1111 and if it is0000 0000, it should just stay 0000 0000.

How would i go about doing that without having to use if statements?

I already tried to do this with bitwise operators, but i couldn't quite figure out how to do this.

I also searched on the internet (also Stackoverflow) on how to do this, but i didn't find anything.

thebear8
  • 194
  • 2
  • 11

3 Answers3

4

A simple if does the job:

if (byte) {
    byte = -1; // 0xFFFF..
}
machine_1
  • 4,266
  • 2
  • 21
  • 42
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • An optimiser can, and for example [clang does](https://godbolt.org/z/YrQ8ii) produce identical code for this, as for the bit twiddling solutions. – eerorika Apr 07 '19 at 13:33
  • Yes it will do fine, but I wanted to avoid if statements. – thebear8 Apr 07 '19 at 13:34
3

You want to set all bits if a is not 0. A simple way to do this is:

unsigned char setallbits(unsigned char a) {
    return (a != 0) ? ~0U : 0;
}

To avoid a test, you can consider that a != 0 will evaluate to 1 or 0, then negate that:

unsigned char setallbits(unsigned char a) {
    return -(a != 0);
}

Or use the idioamtic !!a to convert a to a boolean:

unsigned char setallbits(unsigned char a) {
    return -!!a;
}

The last 2 functions assume two's complement representation of negative values. The purists can achieve portability to obsolete architectures that represent negative integers with sign/magnitude or ones' complement with -(unsigned)(a != 0) or -(unsigned char)!!a which are as cryptic as expected.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Assumes two's complement, but yes, very good solution if that assumption holds (which it almost always does). – ShadowRanger Apr 07 '19 at 13:18
  • @ShadowRanger I heard we're getting guaranteed two's complement in C++20. – HolyBlackCat Apr 07 '19 at 13:19
  • @HolyBlackCat: Yeah, but I think it'll be another few years before we can assume everyone is compiling targeting C++20. – ShadowRanger Apr 07 '19 at 13:19
  • 1
    @ShadowRanger: I added the cast for portability to the DS9K – chqrlie Apr 07 '19 at 13:20
  • 3
    What is this? A lesson in code obfuscation? Have you considered entering the IOCCC? https://www.ioccc.org/ – Richard Hodges Apr 07 '19 at 13:24
  • @RichardHodges: do you like this version better? I have never entered the IOCCC myself, but did motivate a famous multiple winner. – chqrlie Apr 07 '19 at 13:34
  • in the fact !! or != means the `if` in the background – 0___________ Apr 07 '19 at 13:37
  • @P__J__: not necessarily. On x86 it usually generates a `cmp` and a `set ah` from flags. – chqrlie Apr 07 '19 at 13:47
  • @chqrlie: I'd assume it usually generates a `test`, not a `cmp`, given `test` [is (slightly) more efficient](https://stackoverflow.com/a/33724806/364696). In local tests, I reliably see all three versions implemented as `test`, `setne`, `neg`, `retq`. – ShadowRanger Apr 12 '19 at 01:09
0

Not signed version:

unsigned char foo(unsigned char x)
{
    return x ? ~0 : x;
}

All the solutions with !! or != imply the conditional statement.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • unoptimized gcc generates branches for the ternary operator, but not for the `!!` nor the `!=` versions. All three generate the same branchless code with `-O1` or better: https://godbolt.org/z/jSWhqO – chqrlie Apr 07 '19 at 13:59
  • @chqrlie but '-' imlies the two complement - and as I know usually you criticize everyone assuming it for non porability – 0___________ Apr 07 '19 at 15:14
  • `-` applied to a signed int (after promotion) has this problem, not when applied to an `unsigned int` argument. I'm sorry I come across as *criticizing* non portability to non two's complement architectures. I wish two's complement was mandated by the C Standard as it is in POSIX. This portability non-sense is just a byzantine quarrel among experts. It probably puts newbies off and seems futile with good reason. I shall try to be more careful and reserve this to language-lawyer specific questions. – chqrlie Apr 07 '19 at 15:25