简体   繁体   中英

Making a basic algorithm - the more interesting version

See the edit history of "Making a basic algorithm" . There was a palpable sense of disappointment amongst the respondents when OP changed the question, invalidating some interesting answers. So, I figure, why not ask the original question again, to allow those answers to stand.

So basically I want to find a easier way to do this:

 if(size == 2) unit /= 2; if(size == 2 || size == 6) unit /= 2; if(size == 2 || size == 6 || size == 10) unit /= 2; 

So basically it checking if size is equal to 2 and then every new line it add 4 to the last size check.

I need to go up to 256.

I want to know if there a easy way of doing this.

The fundamental criterion on the numbers checked for equality here is that the remained of size / 4 is 2. This can be detected using the modulo operator, % :

size % 4 == 2

Then there is the question of how many times to divide unit by 2. For the examples above:

  • For size == 2 , unit /= 8 (matches all 3 conditions);
  • For size == 6 , unit /= 4 (matches second 2 conditions);
  • For size == 10 , unit /= 2 (matches last condition).

So the smaller the number, the more times it is divided by 8. If the maximum size checked is 10, unit is divided by 2 ^ (1 + (10 - size) / 4) . This can be expressed concisely using the right-shift operator:

unit >>= 1 + (10 - size) / 4

or, more generally:

unit >>= 1 + (max_number - size) / 4

where max_number % 4 == 2 .

Setting max_number = 254 (256 is specified in the question, but wouldn't feature in the expression; the last number checked would be 254), and noting that we only apply this if 2 <= size <= 254 , we can express the final answer as:

if (size % 4 == 2 && size >= 2 && size <= 254) {
  unit >>= 1 + (254 - size) / 4;
}

Actually, the condition can be expressed more concisely (but undoubtedly less readably) as:

if ((size & 0xffffff03) == 2)

As noted by @PaulBoddington, care needs to be taken with the size of the right shift: if unit is an int and the number of bits shifted is greater than 31, then unit should simply be set to zero.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM