My background is computer programming. I am attempting to generate a single number for a mask at compile time, as I know all the parameters for the equation. However, I am struggling to output this brain teaser. Back when I was dealing with fixed point numbers, I was trying to do something similar - which was create a constant which essentially shifts its place value leaving numbers behind, but is also variable.
This is a pretty high level question. I am 100% certain I have seen the answer to my question before in a random place, however, I no longer have access to it.
Goal: Create a number that duplicates a number over several place values.
Correct Conventional Ways
size_t getmask(size_t num_of_bytes) {
size_t out = 0;
for (size_t i=0; i<num_of_bytes; i++) {
out <<= 0x100;
out |= 0xFF;
}
return out;
}
constexpr unsigned mask(unsigned N) { return unsigned(~(-1<<N)); }
constexpr unsigned int mask = ((unsigned int) -1) >> (N * 8);
constexpr unsigned int mask = (0xFFFFFFFF) >> (N * 8);
What I have tried
At first I thought I could generate a sequence, which could be dynamically made. My inputs where 0xFF (255) and I needed a sequence of 0x1010100 + 0x1. When 0xFF * 0x1010101, you get 0xFFFFFFFF. This is brilliant and exactly what I need - shifting the current value over and leaving a value behind. I discovered that I only translated the problem over to then generating a sequence of 0x1010 for a final number of 0x1010100 to add 0x1 to.
printf("%8.8X", 0xFF * 0x1010101);
-> 0xFFFFFFFF
The second runner up was trying to create a sequence like 0x10101. I decided to try using powers and using a trick to shift the place values. 0xFF * 0x10 = 0xFF0, which is similar to that in base10 as, 25 * 10 = 250. So I noted that I can shift the place value by raising 0x10 by a power of the place value. The piece I am missing is placing the value back down in its tread.
printf("%8.8X", 0xFF * pow(0x10, 2));
-> 0x0000FF00
printf("%8.8X", 0xFF * pow(0x10, 3));
-> 0x000FF000
printf("%8.8X", 0xFF * pow(0x10, 4));
-> 0x00FF0000
So I attempted to use 0x101 as the shifter, as I noted that at the end of the sequence 0x1010100 I needed a 1 there. So I plugged in 0x101 into power, but I was unfortunate to gather a rather invalid (but certainly almost correct) sequence.
printf("%8.8X", pow(0x101, 1));
-> 0x00000101
printf("%8.8X", pow(0x101, 2));
-> 0x00010201
printf("%8.8X", pow(0x101, 3));
-> 0x01030301
The two and threes that are embedded into the sequence makes it impossible for my 0xFF constant to be multiplied and create 0xFF, 0xFFFF, and 0xFFFFFF in this situation.
Finally, I am at a loss of what to try next. What I am expecting is 0xFF * some_number * N which when N is 1 = 0xFF, N is 2 = 0xFFFF, N is 3 = 0xFFFFFF, etc. So I am reaching my hands to the math experts of the time to shed some light.
Sorry this question is kind of identity crisis, but I am having a lot of trouble verbalizing what I am looking for due to lack of words to describe it.
Thanks in advance! <3
The answer was quite simple. It just needed clever thinking.
I needed to generate a number such as 0x10101, so that I could multiply 0xNN to the number and receive 0xNNNNNN. Naturally, my first instinct was right - using powers.
In base10, the formula would be
(((pow(10.0, 2.0 * (N - 1))) / 99))where 10 is the base,10^2nis the formula for base10 place value adjustment, N is the number of requested sequences of 10's, and 99 is the max place value that can fit in 2.0 place values. In base16, the formula would be(((pow(16.0, 2.0 * (N - 1))) / 0xFF)). If I wanted to adjust either of these equations to use even more place values, I would alter 2.0 and increase the number of 9's in 99 to match the alteration. The same would be in hexadecimal.