How to build n bit with 1?

I want a function, which takes a int (not a compile time constant).
Gives me back a uint64_t, which has so many 1 as the int parameter.

Is that possible and fast?

1
2
3
  f(1); // 1
  f(5); // 11111
  f(10); // 1111111111  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <cstdlib>
#include <iostream>

constexpr std::uint64_t repeat_one(int n)
{
  constexpr std::uint64_t lut[] = 
  {
    UINT64_C(0),
    UINT64_C(1),                   UINT64_C(11),
    UINT64_C(111),                 UINT64_C(1111),
    UINT64_C(11111),               UINT64_C(111111), 
    UINT64_C(1111111),             UINT64_C(11111111),
    UINT64_C(111111111),           UINT64_C(1111111111),
    UINT64_C(11111111111),         UINT64_C(111111111111),
    UINT64_C(1111111111111),       UINT64_C(11111111111111),
    UINT64_C(111111111111111),     UINT64_C(1111111111111111),
    UINT64_C(11111111111111111),   UINT64_C(111111111111111111),
    UINT64_C(1111111111111111111), UINT64_C(11111111111111111111)
  };
  
  return lut[n];
}

int main()
{
    for (int i = 0; i <= 20; ++i)
        std::cout << repeat_one(i) << '\n';   
}
Last edited on
This does 1 to 64. I can't think of a better way of handling zero than just adding a specific test for it. But if you don't need 0 and you don't need error checking (for negative values or those over 64) then:
1
2
3
uint64_t f(int n) {
    return uint64_t(-1) >> (64 - n);
}

Er, basic bit manipulation:

    (1U << n) - 1

1
2
3
4
constexpr uint64_t repeat_one( int n )
{
  return ((uint64_t)1 << n) - 1;
}

Remember, unsigned rollover IS defined, so this is guaranteed work even if you ask for 64 ones.
Er, not quite.
Remember that shifting by the number of bits or greater is undefined.
Asking for 64 yields 0 for me.

1
2
3
int main() {
    auto x = 1ULL << 64;  // gives a warning
}

Last edited on
Oops! I forgot that.

1
2
3
4
constexpr uint64_t repeat_one( int n )
{
  return ((uint64_t)1 << (n > 64 ? n : 0)) - 1;
}
Topic archived. No new replies allowed.