C++ 如何在编译时计算梅森数

C++ 如何在编译时计算梅森数,c++,c++11,constexpr,C++,C++11,Constexpr,注意:此问答不是关于问题,而是关于问题 我想在编译时计算一个大小为N的数组,其中包含梅森素数(2n− 1) 对于[0,n-1]中的n template <std::uint8_t N> static constexpr std::array<std::uint16_t, N> mersenne_numbers() { // Compute Mersenne numbers for N, N-1 ... 1 and return the array re

注意:此问答不是关于问题,而是关于问题


我想在编译时计算一个大小为N的数组,其中包含梅森素数(2n− 1) 对于[0,n-1]中的n

template <std::uint8_t N>
static constexpr std::array<std::uint16_t, N> mersenne_numbers()
{

    // Compute Mersenne numbers for N, N-1 ... 1 and return the array
    return { 1, 2, 3 };
};

int main()
{
    constexpr std::array<std::uint16_t, 5> arr = mersenne_numbers<5>();
}
模板
静态constexpr std::数组mersenne_numbers()
{
//计算N,N-1…1的梅森数并返回数组
返回{1,2,3};
};
int main()
{
constexpr std::array arr=mersenne_numbers();
}
我如何实现它呢?

因此,要在编译时计算(2^n-1)的数组,您可以这样做

template <std::size_t ... Is>
constexpr std::array<std::uint16_t, sizeof...(Is)>
mersenne_numbers(std::index_sequence<Is...>)
{
    return {{ ((1u << Is) - 1u)... }};
}

template <std::uint8_t N>
constexpr std::array<std::uint16_t, N>
mersenne_numbers()
{
    return mersenne_numbers(std::make_index_sequence<N>{});
}
因此,要在编译时计算(2^n-1)的数组,您可以

template <std::size_t ... Is>
constexpr std::array<std::uint16_t, sizeof...(Is)>
mersenne_numbers(std::index_sequence<Is...>)
{
    return {{ ((1u << Is) - 1u)... }};
}

template <std::uint8_t N>
constexpr std::array<std::uint16_t, N>
mersenne_numbers()
{
    return mersenne_numbers(std::make_index_sequence<N>{});
}
使用C++14:

#include <iostream>
#include <array>
#include <type_traits>

constexpr int cpow2(int n) {
  return n == 0 ? 1 : 2 * cpow2(n-1);
}

template <size_t... Seq>
static constexpr std::array<size_t, sizeof...(Seq)> mersenne_numbers(std::index_sequence<Seq...> isq)
{
  return {(cpow2(Seq)-1)...};
}


int main() {
  static_assert (cpow2(4) == 16, "");
  auto arr = mersenne_numbers(std::make_index_sequence<5>());
  for (auto e : arr) std::cout << e << " ";
  std::cout << std::endl;
  return 0;
}
#包括
#包括
#包括
constexpr int cpow2(int n){
返回n==0?1:2*cpow2(n-1);
}
模板
静态constexpr std::数组mersenne_数(std::index_序列isq)
{
返回{(cpow2(Seq)-1)…};
}
int main(){
静态断言(cpow2(4)=16,”;
自动arr=mersenne_编号(std::make_index_sequence());
对于使用C++14的(自动e:arr)std::cout:

#include <iostream>
#include <array>
#include <type_traits>

constexpr int cpow2(int n) {
  return n == 0 ? 1 : 2 * cpow2(n-1);
}

template <size_t... Seq>
static constexpr std::array<size_t, sizeof...(Seq)> mersenne_numbers(std::index_sequence<Seq...> isq)
{
  return {(cpow2(Seq)-1)...};
}


int main() {
  static_assert (cpow2(4) == 16, "");
  auto arr = mersenne_numbers(std::make_index_sequence<5>());
  for (auto e : arr) std::cout << e << " ";
  std::cout << std::endl;
  return 0;
}
#包括
#包括
#包括
constexpr int cpow2(int n){
返回n==0?1:2*cpow2(n-1);
}
模板
静态constexpr std::数组mersenne_数(std::index_序列isq)
{
返回{(cpow2(Seq)-1)…};
}
int main(){
静态断言(cpow2(4)=16,”;
自动arr=mersenne_编号(std::make_index_sequence());

对于(auto e:arr)std::cout来说,我不太了解马森数,但您可以随时修改此示例 (计算
x^x
):

模板
constexpr std::阵列电源
(std::阵列arr,
const uint8_t num)
{
arr[num]=static_cast(std::pow(num,num));
返回arr;
}
模板
constexpr std::阵列自供电
(std::array arr=std::array{0},
const uint8_t step=0)
{
返回步骤>=N?arr:自供电(电源一(arr,步骤),步骤+1);
}
s32 main()
{
自动arr=自供电();
用于(自动和x:arr)
{

std::cout不太了解马森数,但您可以随时修改此示例 (计算
x^x
):

模板
constexpr std::阵列电源
(std::阵列arr,
const uint8_t num)
{
arr[num]=static_cast(std::pow(num,num));
返回arr;
}
模板
constexpr std::阵列自供电
(std::array arr=std::array{0},
const uint8_t step=0)
{
返回步骤>=N?arr:自供电(电源一(arr,步骤),步骤+1);
}
s32 main()
{
自动arr=自供电();
用于(自动和x:arr)
{


std::cout@lordjohncena好问题。问题的标题有误导性,应该是如何在编译时计算mesenne数。摘自“只有疯子才会尝试在C++11 constexpr中实现Mersenne Twister。”有一点是编译时计算非常复杂,你最好写一个程序,把你需要的任何东西都转储到数据文件中;或者如果你需要一个头文件作为编译时常数。伙计们……这是关于,而不是Mersenne twister。@lordjohncena问得好。问题的标题是误导,应该是如何在编译时计算mesenne数。摘自“只有疯子才会尝试在C++11 constexpr中实现Mersenne Twister”有一点,编译时计算是如此复杂,你最好写一个程序,将你需要的任何东西转储到数据文件中;或者如果你需要一个头文件作为编译时常量。伙计们……这是关于,而不是Mersenne twister。我同意这是可行的,但我很好奇……如果我说我们不需要tem,我错了吗plate元编程在编译时计算这个?Ref:@lordjohncena:
constexpr
函数在c++11中受到限制,但c++14允许以自然的方式编写。请参阅编辑。谢谢,如果可以的话,我会加倍投票!我同意这是可行的,但我很好奇……如果我说我们不需要模板元编程来计算这个,我错了吗编译时?Ref:@lordjohncena:
constexpr
函数在c++11中受到限制,但c++14允许以自然的方式编写。请参阅编辑。谢谢,如果可以的话,我会加倍投票!使用
constexpr
失败,即使没有它也会计算
x^x
@Jarod42好吧,我已经在IDE中将c++14设置为默认值,所以我是我的疏忽。关于什么它计算,它应该计算
x^x
,因为它只是一个如何实现这种机制的示例:)
std::pow
不是
constexpr
。如果没有它,它会失败
constexpr
,即使没有它也会计算
x^x
@Jarod42。好吧,我在IDE中已经将c++14设置为默认值,所以我是我的疏忽。关于它所涉及的内容在计算机中,它应该计算
x^x
,因为它只是实现这种机制的一个示例:)
std::pow
不是
constepr