Background
Consider the following:
template <unsigned N>
struct Fibonacci
{
enum
{
value = Fibonacci<N-1>::value + Fibonacci<N-2>::value
};
};
template <>
struct Fibonacci<1>
{
enum
{
value = 1
};
};
template <>
struct Fibonacci<0>
{
enum
{
value = 0
};
};
This is a common example and we can get the value of a Fibonacci number as a compile-time constant:
int main(void)
{
std::cout << "Fibonacci(15) = ";
std::cout << Fibonacci<15>::value;
std::cout << std::endl;
}
But you obviously cannot get the value at runtime:
int main(void)
{
std::srand(static_cast<unsigned>(std::time(0)));
// ensure the table exists up to a certain size
// (even though the rest of the code won't work)
static const unsigned fibbMax = 20;
Fibonacci<fibbMax>::value;
// get index into sequence
unsigned fibb = std::rand() % fibbMax;
std::cout << "Fibonacci(" << fibb << ") = ";
std::cout << Fibonacci<fibb>::value;
std::cout << std::endl;
}
Because fibb is not a compile-time constant.
Question
So my question is:
What is the best way to peek into this table at run-time? The most obvious solution (and "solution" should be taken lightly), is to have a large switch statement:
unsigned fibonacci(unsigned index)
{
switch (index)
{
case 0:
return Fibonacci<0>::value;
case 1:
return Fibonacci<1>::value;
case 2:
return Fibonacci<2>::value;
.
.
.
case 20:
return Fibonacci<20>::value;
default:
return fibonacci(index - 1) + fibonacci(index - 2);
}
}
int main(void)
{
std::srand(static_cast<unsigned>(std::time(0)));
static const unsigned fibbMax = 20;
// get index into sequence
unsigned fibb = std::rand() % fibbMax;
std::cout << "Fibonacci(" << fibb << ") = ";
std::cout << fibonacci(fibb);
std::cout << std::endl;
}
But now the size of the table is very hard coded and it wouldn't be easy to expand it to say, 40.
The only one I came up with that has a similiar method of query is this:
template <int TableSize = 40>
class FibonacciTable
{
public:
enum
{
max = TableSize
};
static unsigned get(unsigned index)
{
if (index == TableSize)
{
return Fibonacci<TableSize>::value;
}
else
{
// too far, pass downwards
return FibonacciTable<TableSize - 1>::get(index);
}
}
};
template <>
class FibonacciTable<0>
{
public:
enum
{
max = 0
};
static unsigned get(unsigned)
{
// doesn't matter, no where else to go.
// must be 0, or the original value was
// not in table
return 0;
}
};
int main(void)
{
std::srand(static_cast<unsigned>(std::time(0)));
// get index into sequence
unsigned fibb = std::rand() % FibonacciTable<>::max;
std::cout << "Fibonacci(" << fibb << ") = ";
std::cout << FibonacciTable<>::get(fibb);
std::cout << std::endl;
}
Which seems to work great. The only two problems I see are:
Potentially large call stack, since calculating Fibonacci<2> requires we go through TableMax all the way to 2, and:
If the value is outside of the table, it returns zero as opposed to calculating it.
So is there something I am missing? It seems there should be a better way to pick out these values at runtime.
A template metaprogramming version of a switch statement perhaps, that generates a switch statement up to a certain number?
Thanks in advance.
template <unsigned long N>
struct Fibonacci
{
enum
{
value = Fibonacci<N-1>::value + Fibonacci<N-2>::value
};
static void add_values(vector<unsigned long>& v)
{
Fibonacci<N-1>::add_values(v);
v.push_back(value);
}
};
template <>
struct Fibonacci<0>
{
enum
{
value = 0
};
static void add_values(vector<unsigned long>& v)
{
v.push_back(value);
}
};
template <>
struct Fibonacci<1>
{
enum
{
value = 1
};
static void add_values(vector<unsigned long>& v)
{
Fibonacci<0>::add_values(v);
v.push_back(value);
}
};
int main()
{
vector<unsigned long> fibonacci_seq;
Fibonacci<45>::add_values(fibonacci_seq);
for (int i = 0; i <= 45; ++i)
cout << "F" << i << " is " << fibonacci_seq[i] << '\n';
}
After much thought into the problem, I came up with this solution. Of course, you still have to add the values to a container at run-time, but (importantly) they are not computed at run-time.
As a side note, it's important not to define Fibonacci<1> above Fibonacci<0>, or your compiler will get very confused when it resolves the call to Fibonacci<0>::add_values, since Fibonacci<0>'s template specialization has not been specified.
Of course, TMP has its limitations: You need a precomputed maximum, and getting the values at run-time requires recursion (since templates are defined recursively).
I know this question is old, but it intrigued me and I had to have a go at doing without a dynamic container filled at runtime:
#ifndef _FIBONACCI_HPP
#define _FIBONACCI_HPP
template <unsigned long N>
struct Fibonacci
{
static const unsigned long long value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
static unsigned long long get_value(unsigned long n)
{
switch (n) {
case N:
return value;
default:
return n < N ? Fibonacci<N-1>::get_value(n)
: get_value(n-2) + get_value(n-1);
}
}
};
template <>
struct Fibonacci<0>
{
static const unsigned long long value = 0;
static unsigned long long get_value(unsigned long n)
{
return value;
}
};
template <>
struct Fibonacci<1>
{
static const unsigned long long value = 1;
static unsigned long get_value(unsigned long n)
{
if(n == N){
return value;
}else{
return 0; // For `Fibonacci<N>::get(0);`
}
}
};
#endif
This seems to work, and when compiled with optimizations (not sure if you were going to allow that), the call stack does not get to deep - there is normal runtime recursion on the stack of course for values (arguments) n > N, where N is the TableSize used in the template instantiation. However, once you go below the TableSize the generated code substitutes a constant computed at compile time, or at worst a value "computed" by dropping through a jump table (compiled in gcc with -c -g -Wa,-adhlns=main.s and checked the listing), the same as I reckon your explicit switch statement would result in.
When used like this:
int main()
{
std::cout << "F" << 39 << " is " << Fibonacci<40>::get_value(39) << '\n';
std::cout << "F" << 45 << " is " << Fibonacci<40>::get_value(45) << '\n';
}
There is no call to a computation at all in the first case (value computed at compile time), and in the second case the call stack depth is at worst:
fibtest.exe!Fibonacci<40>::get_value(unsigned long n=41) Line 18 + 0xe bytes C++
fibtest.exe!Fibonacci<40>::get_value(unsigned long n=42) Line 18 + 0x2c bytes C++
fibtest.exe!Fibonacci<40>::get_value(unsigned long n=43) Line 18 + 0x2c bytes C++
fibtest.exe!Fibonacci<40>::get_value(unsigned long n=45) Line 18 + 0xe bytes C++
fibtest.exe!main() Line 9 + 0x7 bytes C++
fibtest.exe!__tmainCRTStartup() Line 597 + 0x17 bytes C
I.e. it recurses until it finds a value in the "Table". (verified by stepping through Disassembly in the debugger line by line, also by replacing the test ints by a random number <= 45)
The recursive part could also be replaced by the linear iterative solution:
static unsigned long long get_value(unsigned long n)
{
switch (n) {
case N:
return value;
default:
if (n < N) {
return Fibonacci<N-1>::get_value(n);
} else {
// n > N
unsigned long long i = Fibonacci<N-1>::value, j = value, t;
for (unsigned long k = N; k < n; k++) {
t = i + j;
i = j;
j = t;
}
return j;
}
}
}
If you have C++ compiler which supports variadic templates (C++0x standard ) you can save fibonacii sequence in a tuple at the compile time. At runtime you can access any element from that tuple by indexing.
#include <tuple>
#include <iostream>
template<int N>
struct Fib
{
enum { value = Fib<N-1>::value + Fib<N-2>::value };
};
template<>
struct Fib<1>
{
enum { value = 1 };
};
template<>
struct Fib<0>
{
enum { value = 0 };
};
// ----------------------
template<int N, typename Tuple, typename ... Types>
struct make_fibtuple_impl;
template<int N, typename ... Types>
struct make_fibtuple_impl<N, std::tuple<Types...> >
{
typedef typename make_fibtuple_impl<N-1, std::tuple<Fib<N>, Types... > >::type type;
};
template<typename ... Types>
struct make_fibtuple_impl<0, std::tuple<Types...> >
{
typedef std::tuple<Fib<0>, Types... > type;
};
template<int N>
struct make_fibtuple : make_fibtuple_impl<N, std::tuple<> >
{};
int main()
{
auto tup = typename make_fibtuple<25>::type();
std::cout << std::get<20>(tup).value;
std::cout << std::endl;
return 0;
}
With C++11: you may create a std::array and a simple getter: https://ideone.com/F0b4D3
namespace detail
{
template <std::size_t N>
struct Fibo :
std::integral_constant<size_t, Fibo<N - 1>::value + Fibo<N - 2>::value>
{
static_assert(Fibo<N - 1>::value + Fibo<N - 2>::value >= Fibo<N - 1>::value,
"overflow");
};
template <> struct Fibo<0u> : std::integral_constant<size_t, 0u> {};
template <> struct Fibo<1u> : std::integral_constant<size_t, 1u> {};
template <std::size_t ... Is>
constexpr std::size_t fibo(std::size_t n, index_sequence<Is...>)
{
return const_cast<const std::array<std::size_t, sizeof...(Is)>&&>(
std::array<std::size_t, sizeof...(Is)>{{Fibo<Is>::value...}})[n];
}
template <std::size_t N>
constexpr std::size_t fibo(std::size_t n)
{
return n < N ?
fibo(n, make_index_sequence<N>()) :
throw std::runtime_error("out of bound");
}
} // namespace detail
constexpr std::size_t fibo(std::size_t n)
{
// 48u is the highest
return detail::fibo<48u>(n);
}
In C++14, you can simplify some function:
template <std::size_t ... Is>
constexpr std::size_t fibo(std::size_t n, index_sequence<Is...>)
{
constexpr std::array<std::size_t, sizeof...(Is)> fibos{{Fibo<Is>::value...}};
return fibos[n];
}
My idea is to recursively save the fibonacci sequence in the variadic templates then convert it into an array. All of this are done at compile-time.
For example with n = 5 we have:
F<5>::array
= F<4, 0>::array
= F<3, 0, 1>::array
= F<2, 0, 1, 1>::array
= F<1, 0, 1, 1, 2>::array
= F<0, 0, 1, 1, 2, 3>::array
= { 0, 1, 1, 2, 3 }
Then we can index the array at runtime.
My C++14 implementation:
#include <cstdint>
#include <array>
#include <iostream>
template<uint64_t n>
struct Helper { static constexpr uint64_t value = Helper<n - 1>::value + Helper<n - 2>::value; };
template<>
struct Helper<0> { static constexpr uint64_t value = 0; };
template<>
struct Helper<1> { static constexpr uint64_t value = 1; };
template<u_int64_t x>
class Fib {
private:
template<u_int64_t n, u_int64_t...rest>
struct Get {
static constexpr std::array<u_int64_t, n + sizeof...(rest)> value = Get<n - 1, rest..., Helper<sizeof...(rest)>::value>::value;
};
template<u_int64_t...rest>
struct Get<0, rest...> {
static constexpr std::array<u_int64_t, sizeof...(rest)> value{rest...};
};
public:
static constexpr std::array<u_int64_t, x> sequence = Get<x>::value;
};
template<u_int64_t x>
constexpr std::array<u_int64_t, x> Fib<x>::sequence;
int main() {
for (int i = 0; i < 45; i++) std::cout << "F" << i << " = " << Fib<45>::sequence[i] << std::endl;
}
One of the basic tennants of C (and for the most part C++) is that you don't pay for what you don't need.
The automatic generation of look-up tables is just not something that the compiler needs to do for you. Even if you need that functionality, not everyone else necessarly does.
If you want a lookup table, write a program to make one. Then use that data in your program.
Don't use a template metaprogram if you want values to be calculated at runtime, just use a regular program to calculate values.
You can generate the switch or a static array using preprocessor metaprogramming techniques.
It is a good decision if the complexity does not exceed the limitations of that approach, and you prefer not extending your toolchain with extra steps that generate code or data.
Related
I want to define template which would behave similar to power function a^n
a^n = -1 where a < 0 or n < 0
a^0 = 0 (so not exactly as std::pow)
otherwise std::pow
I have a problem defining the condition for point 1 - I assume this will be a combination of enable_if and some defined constexpr checking whether integer is negative.
What I wrote for the 1. point (commented out below) probably does not make sense as it do not compile. I am only starting with metaprogramming, to be honest I do not quite understand it. I would much appreciate if you could provide explanation and/or some resources you found helpful while getting into the topic.
#include <iostream>
#include <cmath>
// std::pow
template <int a, int n>
struct hc {
enum { v = a * hc<a, n - 1>::v };
};
// to break recursion from getting to a^0=0
template <int a>
struct hc<a, 1> {
enum { v = a };
};
// a^0 = 0
template <int a>
struct hc<a, 0> {
enum { v = 0 };
};
// a^n=-1 for negative a or n
/*
template <int i>
constexpr bool is_negative = i < 0;
// a ^ n = -1, where a < 0 or n < 0
template <int a, int n,
typename std::enable_if<is_negative<a> || is_negative<n>>::type>
struct hc {
enum { v = -1 };
};
*/
int main() {
// a^0=0
std::cout << hc<0, 0>::v << " -> 0^0=0\n";
std::cout << hc<3, 0>::v << " -> 3^0=0\n";
// a^n=std::pow
std::cout << hc<1, 1>::v << " -> 1^1=" << std::pow(1, 1) << '\n';
std::cout << hc<2, 2>::v << " -> 2^2=" << std::pow(2, 2) << '\n';
std::cout << hc<0, 2>::v << " -> 0^2=" << std::pow(0, 2) << '\n';
std::cout << hc<3, 2>::v << " -> 3^2=" << std::pow(3, 2) << '\n';
std::cout << hc<3, 7>::v << " -> 3^7=" << std::pow(3, 7) << '\n';
// a^n=-1 for negative a or n
std::cout << hc<-3, 7>::v << " -> -3^7=-1\n";
std::cout << hc<3, -7>::v << " -> 3^-7=-1\n";
std::cout << hc<0, -7>::v << " -> 0^7=-1\n";
std::cout << hc<-3, 0>::v << " -> -3^0=-1\n";
}
There are several ways
Simpler IMO, would be constexpr function
constexpr int hc_impl(int a, int n)
{
if (a < 0 || n < 0) return -1;
if (n == 0) return 0;
int res = 1;
for (int i = 0; i != n; ++n) {
res *= a;
}
return res;
};
template <int a, int n>
struct hc
{
constexpr int v = hc_impl(a, n);
};
The old way with struct, you might add an extra parameter for dispatch, something like:
template <int a, int n, bool b = (a < 0 || n < 0)>
struct hc;
template <int a, int n>
struct hc<a, n, true> {
enum { v = -1 };
};
template <int a>
struct hc<a, 1, true> {
enum { v = -1 };
};
template <int a>
struct hc<a, 0, true> {
enum { v = -1 };
};
template <int a, int n>
struct hc<a, n, false> {
enum { v = a * hc<a, n - 1>::v };
};
// to break recursion from getting to a^0=0
template <int a>
struct hc<a, 1, false> {
enum { v = a };
};
// a^0 = 0
template <int a>
struct hc<a, 0, false> {
enum { v = 0 };
};
This is how I would do it using template constexpr:
template<int a, int n>
constexpr int pow()
{
if ((a < 0) || (n < 0)) return -1;
if (n == 0) return 0;
int result = 1;
for (int i = 0; i < n; i++) result *= a;
return result;
}
int main()
{
static_assert(pow<0,0>() == 0);
static_assert(pow<2, 0>() == 0);
static_assert(pow<-1, 0>() == -1);
static_assert(pow<1, -1>() == -1);
static_assert(pow<2, 3>() == 8);
}
Your partial specialization syntax for the last case is incorrect: you should have something inside <> after template<.....> struct hn.
So, something like this will almost work:
// a ^ n = -1, where a < 0 or n < 0
template <int a, int n,
typename std::enable_if<is_negative<a> || is_negative<n>>::type>
struct hc<a, n> {
enum { v = -1 };
};
enable_if::type is a type which you have to put into a position where it can be SFINAE'd, not just somewhere inside template<>. You typically put it either inside a function signature or inside a partial template specialization.
Like this:
// You have to change your general case definition.
// std::pow
template<int a, int n, typename /*DummyUnusedType*/ = void>
struct hc {
enum { v = a * hc<a, n - 1>::v };
};
// ... your existing definitions here ...
// a ^ n = -1, where a < 0 or n < 0
template <int a, int n>
struct hc<a, n, typename std::enable_if<is_negative<a> || is_negative<n>>::type> {
enum { v = -1 };
};
You actually don't even need is_negative and typename:
struct hc<a, n, std::enable_if_t<(a < 0 || n < 0)>> { // Parens are optional
The only remaining problem is that your <a, 0> case intersects with this one for negative as. You can restrict it for non-negative as using the same trick.
In general, though, constexpr function are superior, as suggested by other answers.
Is it possible to create a const array of objects where one member variable is the sum of a member variable in the objects created before it?
class Data
{
public:
constexpr Data(uint32_t offset, uint32_t length) :
m_offset(offset), m_length(length)
{
}
uint32_t m_offset; //would like this to be calculated at compile time
uint32_t m_length;
};
const Data dataList[] =
{
Data(0, 10),
Data(10, 25),
Data(35, 20)
};
offset is the sum of the length of all previous objects in the array (10 + 25 = 35 in index 2).
I'd like to avoid having to manually calculate the offset.
I've played around with std::integral_constant and recursive calls to constexpr, but nothing seems close enough to a working solution to share. Any guidance is much appreciated!
If you accept an answer based on a std::array<Data, ...> instead of a old C-style array, and to use C++14 instead of C++11, it's easy
The following is a full example
#include <array>
#include <iostream>
struct Data
{
constexpr Data(uint32_t offset, uint32_t length) :
m_offset(offset), m_length(length)
{ }
uint32_t m_offset;
uint32_t m_length;
};
template <uint32_t ... Ls>
constexpr std::array<Data, sizeof...(Ls)> getDataList ()
{
uint32_t l0 { 0U };
uint32_t l1 { 0U };
return { { (l0 = l1, l1 += Ls, Data(l0, l1))... } };
}
int main ()
{
constexpr auto dl = getDataList<10U, 25U, 20U>();
for ( auto const & d : dl )
std::cout << " - " << d.m_offset << ", " << d.m_length << std::endl;
}
-- EDIT --
The OP can't use std::array but a C++ function can't return a C-style array; a solution could be simulate a (iper-simplified) version of std::array, that wrap a C-style array in a trivial struct
template <typename T, std::size_t N>
struct myArray
{ T arr[N]; };
Now the full example become
#include <array>
#include <iostream>
template <typename T, std::size_t N>
struct myArray
{ T arr[N]; };
struct Data
{
constexpr Data(uint32_t offset, uint32_t length) :
m_offset(offset), m_length(length)
{ }
uint32_t m_offset;
uint32_t m_length;
};
template <uint32_t ... Ls>
constexpr myArray<Data, sizeof...(Ls)> getDataList ()
{
uint32_t l0 { 0 };
uint32_t l1 { 0 };
return { { (l0 = l1, l1 += Ls, Data(l0, l1))... } };
}
int main ()
{
constexpr auto dl = getDataList<10U, 25U, 20U>();
for ( auto ui = 0U ; ui < 3U ; ++ui )
std::cout << " - " << dl.arr[ui].m_offset << ", "
<< dl.arr[ui].m_length << std::endl;
}
The std::array simulation can be a little less iper-simplified and contain, by example, a static constexpr member with the dimension
template <typename T, std::size_t N>
struct myArray
{ static constexpr std::size_t dim { N }; T arr[dim]; };
so the loop in main() can use it
// ..........................vvv
for ( auto ui = 0U ; ui < dl.dim ; ++ui )
I need to store the array of first N Fibonacci numbers.
const int N = 100;
long long int fib[N] = {0};
fib[0] = 1;
fib[1] = 1;
for(int i = 2; i < N; ++i)
fib[i] = fib[i-2] + fib[i-1];
return 0;
Is it possible to make fib[] constexpr, and evaluate it at compilation time somehow ?
First of all you have to write Fibonacci algorithm in compile time version, so consider following:
template <size_t N>
struct Fibo {
static constexpr const size_t value {Fibo<N-2>::value + Fibo<N-1>::value};
};
template <>
struct Fibo<0> {
static constexpr const size_t value {1};
};
template <>
struct Fibo<1> {
static constexpr const size_t value {1};
};
and you can use this as simply as that:
std::cout << Fibo<0>::value << std::endl;
std::cout << Fibo<1>::value << std::endl;
std::cout << Fibo<2>::value << std::endl;
std::cout << Fibo<3>::value << std::endl;
std::cout << Fibo<10>::value << std::endl;
std::cout << Fibo<50>::value << std::endl;
and output values are:
1
1
2
3
89
20365011074
But this is still not you are looking for.
I do not know if you can make constexpr array (but probably there is a possibility), but you can do it slightly different. Consider:
template <size_t N>
struct Storage {
static size_t data[N+1];
};
template <size_t N> size_t Storage<N>::data[N+1] {};
template <size_t N, size_t F>
struct Filler {
static constexpr void fill () {
Storage<N>::data[F] = Fibo<F>::value;
Filler<N, F-1>::fill ();
}
};
template <size_t N>
struct Filler<N, 0> {
static constexpr void fill () {
Storage<N>::data[0] = Fibo<0>::value;
}
};
template <size_t N>
struct Calc {
static constexpr void calc () {
Filler<N, N>::fill ();
}
};
and the usage would be like this:
constexpr const size_t N = 12;
Calc<N>::calc ();
size_t* ptr = Storage<N>::data;
for (int i = 0; i <= N; ++i) {
std::cout << ptr[i] << std::endl;
}
and output:
1
1
2
3
5
8
13
21
34
55
89
144
233
What is important here is the Storage class which stores our array with appropriate number of elements.
General Filler class (with two template parameters) is used for any F value that can be passed, except value of 0. Because if we reach the 0 index, we don't want to call once again fill() member function, because we are done. So that's the reason why partial specialization of Filler class exists.
Hope I can help with this.
There is a way (ugly one), but I can't think of anything else.
#include <iostream>
#include <cmath>
constexpr unsigned long long f(int x)
{
return 1/sqrt(5)*pow(((1+sqrt(5))/2),x) - 1/sqrt(5)*pow(((1-sqrt(5))/2),x);
}
#define FIBB1(x) 1
#define FIBB2(x) FIBB1(x-1),1
#define FIBB3(x) FIBB2(x-1),f(x)
#define FIBB4(x) FIBB3(x-1),f(x)
#define FIBB5(x) FIBB4(x-1),f(x)
#define FIBB6(x) FIBB5(x-1),f(x)
#define FIBB7(x) FIBB6(x-1),f(x)
#define FIBB8(x) FIBB7(x-1),f(x)
#define FIBB9(x) FIBB8(x-1),f(x)
#define FIBB10(x) FIBB9(x-1),f(x)
#define FIBB11(x) FIBB10(x-1),f(x)
#define FIBB12(x) FIBB11(x-1),f(x)
#define FIBB13(x) FIBB12(x-1),f(x)
#define FIBB14(x) FIBB13(x-1),f(x)
#define FIBB15(x) FIBB14(x-1),f(x)
#define FIBB16(x) FIBB15(x-1),f(x)
#define FIBB17(x) FIBB16(x-1),f(x)
#define FIBB18(x) FIBB17(x-1),f(x)
#define FIBB19(x) FIBB18(x-1),f(x)
#define FIBB20(x) FIBB19(x-1),f(x)
// ...
#define FIBB93(x) FIBB92(x-1),f(x)
//#define FIBB94(x) FIBB93(x-1),f(x) //unsigned long long overflow, can't calculate more
#define FIBB(x) {FIBB##x(x)}
constexpr unsigned long long fib[93] = FIBB(93);
int main()
{
// all possible fibbonacci numbers for unsigned long long implementation
for(int i=0; i<93; ++i)
std::cout << fib[i] << std::endl;
}
I think it's the only way for C++ built-in array.
Here's a C++14 solution (GCC >= 5.0.0, Clang >= 3.5.0) using a template argument for the length. You write an imperative loop (identical to your original post) in a constexpr function. Using a disassembler, you can see the sequence is embedded into the program as raw data, even with no optimizations (-O0).
#include <array>
#include <cstddef>
#include <iostream>
#include <type_traits>
#include <utility>
namespace {
// Create an std::array from a C array (internal) via an
// std::index_sequence.
template <typename T, typename TSequence> struct MakeArrayImpl;
template <typename T, std::size_t... TIndices>
struct MakeArrayImpl<T, std::index_sequence<TIndices...>> {
static constexpr std::array<T, sizeof...(TIndices)>
make_array(T values[sizeof...(TIndices)]) {
return std::array<T, sizeof...(TIndices)>{{values[TIndices]...}};
}
};
// Create an std::array from a C array.
template <typename T, std::size_t TLength>
constexpr std::array<T, TLength> make_array(T values[TLength]) {
return MakeArrayImpl<T, std::make_index_sequence<TLength>>::make_array(
values);
}
// Return an std::array of the first numbers in the Fibonacci sequence.
template <std::size_t TLength>
constexpr std::array<long long int, TLength> fibs() {
// Original algorithm.
long long int fib[TLength] = {0};
fib[0] = 1;
fib[1] = 1;
for (std::size_t i = 2; i < TLength; ++i) {
fib[i] = fib[i - 2] + fib[i - 1];
}
return make_array<long long int, TLength>(fib);
}
}
int main() {
// Original algorithm.
const int N = 92;
long long int fib[N] = {0};
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i < N; ++i)
fib[i] = fib[i - 2] + fib[i - 1];
// Test constexpr algorithm against original algorithm.
static constexpr auto values = fibs<N>();
static_assert(values.size() == N, "Expected N values in Fibs");
for (int i = 0; i < N; ++i) {
if (fib[i] != values[i]) {
std::cerr << "Mismatch at index " << i << "\n";
std::cerr << "Expected: " << fib[i] << "\n";
std::cerr << "Actual : " << values[i] << "\n";
}
}
}
In the code sample you posted, there is a decent chance that the compiler may unroll the loop, or at least part of it, on its own, if -O3 optimizations are used. Playing around on godbolt, it appears that this doesn't happen at N=100 but does at N up to about 40. In this case it does happen at compile time, whether or not it is constexpr.
Which also points out -- on many machines, long long int is not large enough to hold the 100'th fibonacci number. Fibonacci numbers grow exponentially, you should expect the 100th number to require about 100 bits or so. Your code as written will exhibit undefined behavior due to integer overflow, on a typical machine.
Using a template you can do it like this:
// Fibonacci recurrence
template <long int n>
struct fib_pair {
typedef fib_pair<n-1> prev;
static constexpr long int fib_n = prev::fib_n_plus_one;
static constexpr long int fib_n_plus_one = prev::fib_n + prev::fib_n_plus_one;
};
template <>
struct fib_pair<0> {
static constexpr long int fib_n = 0;
static constexpr long int fib_n_plus_one = 1;
};
// List structure
template <long int ... > struct list {};
// Concat metafunction
template <typename A, typename B> struct concat;
template <long int... As, long int... Bs> struct concat<list<As...>, list<Bs...>> {
typedef list<As..., Bs...> type;
};
// Get a sequence from the fib_pairs
template <long int n>
struct fib_seq {
typedef typename fib_seq<n-1>::type prev;
typedef typename concat<prev, list<fib_pair<n>::fib_n>>::type type;
};
template <>
struct fib_seq<0> {
typedef list<0> type;
};
// Make an array from pack expansion
#include <array>
template <typename T> struct helper;
template <long int ... nums>
struct helper <list<nums...>> {
typedef std::array<const long int, sizeof...(nums)> array_type;
static constexpr array_type get_array() {
return {{ nums... }};
}
};
// Easy access
template <long int n>
constexpr std::array<const long int, n + 1> get_fib_array() {
return helper<typename fib_seq<n>::type>::get_array();
}
#include <iostream>
int main () {
for (const long int x : get_fib_array<15>()) {
std::cout << x << std::endl;
}
}
Here's a C++11 solution using C++14 library features [1] (GCC >= 4.9.0, Clang >= 3.5.0) using a template argument for the length. You write a loop using recursion. Using a disassembler, you can see the sequence is embedded into the program as raw data, even with no optimizations (-O0).
[1] std::index_sequence can be implemented yourself in C++11 if it is not available in your standard library.
#include <array>
#include <cstddef>
#include <iostream>
#include <type_traits>
#include <utility>
namespace {
// Create an std::array from a C array (internal) via an
// std::index_sequence.
template <typename T, typename TSequence> struct MakeArrayImpl;
template <typename T, std::size_t... TIndices>
struct MakeArrayImpl<T, std::index_sequence<TIndices...>> {
static constexpr std::array<T, sizeof...(TIndices)>
make_array(T values[sizeof...(TIndices)]) {
return std::array<T, sizeof...(TIndices)>{{values[TIndices]...}};
}
};
// Create an std::array from a C array.
template <typename T, std::size_t TLength>
constexpr std::array<T, TLength> make_array(T values[TLength]) {
return MakeArrayImpl<T, std::make_index_sequence<TLength>>::make_array(
values);
}
// Return an std::array of the first numbers in the Fibonacci sequence.
template <std::size_t TLength>
constexpr std::array<long long int, TLength> fibs() {
// Original algorithm.
long long int fib[TLength] = {0};
fib[0] = 1;
fib[1] = 1;
for (std::size_t i = 2; i < TLength; ++i) {
fib[i] = fib[i - 2] + fib[i - 1];
}
return make_array<long long int, TLength>(fib);
}
}
int main() {
// Original algorithm.
const int N = 92;
long long int fib[N] = {0};
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i < N; ++i)
fib[i] = fib[i - 2] + fib[i - 1];
// Test constexpr algorithm against original algorithm.
static constexpr auto values = fibs<N>();
static_assert(values.size() == N, "Expected N values in Fibs");
for (int i = 0; i < N; ++i) {
if (fib[i] != values[i]) {
std::cerr << "Mismatch at index " << i << "\n";
std::cerr << "Expected: " << fib[i] << "\n";
std::cerr << "Actual : " << values[i] << "\n";
}
}
}
I am trying to solve Problem 2 on Project Euler. The problem is:
"Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms."
I am trying to solve this in C++.
Here is my code so far
#include <iostream>
using namespace std;
int main()
{
//ANSWER = 4613732
int max = 4000000;
int n;
int sum;
for(n=0; n<=max;)
{
while(n%2 == 0)
{
n = (n-1)+(n-2);
}
}
sum = n+=0;
cout << sum << endl;
return 0;
}
As you can see I know the correct answer from searching for it to check my answer. This code I have just runs forever and never shows an answer. Can anyone give me hints on how to arrive to this answer and to help improve my C++ code. Thanks in advance!
Here is an approach you should not follow. (Note: this post is a joke, but I'm serious about not following this approach. Attempting to understand this approach at your level of C++ understanding is also ill advised.)
#include <iostream>
struct Fib
{
template<int n, int first=1, int second=1> struct Eval { enum {value = Eval<n-1, first, second>::value + Eval<n-2, first, second>::value}; };
template<int first, int second> struct Eval<1, first, second> { enum {value = second}; };
template<int first, int second> struct Eval<0, first, second> { enum {value = first}; };
};
struct SpecificFib
{
template<int n> struct Eval { enum{ value = Fib::template Eval<n, 1, 2>::value }; };
};
template<int... values> struct Sequence {};
template<typename Seq, int n> struct Append;
template<int... values, int n> struct Append<Sequence<values...>, n> { typedef Sequence<values...,n> type; };
template<typename Seq, int n> struct Prepend;
template<int... values, int n> struct Prepend<Sequence<values...>, n> { typedef Sequence<n, values...> type; };
template<typename Func,typename Seq,typename Test=void> struct Filter;
template<typename Func,int first, int... values>
struct Filter<Func,Sequence<first,values...>,typename std::enable_if< Func::template Eval<first>::value>::type>
{
typedef typename Prepend<typename Filter<Func,Sequence<values...>>::type,first>::type type;
};
template<typename Func,int first, int... values>
struct Filter<Func,Sequence<first,values...>,typename std::enable_if< !Func::template Eval<first>::value>::type>
{
typedef typename Filter<Func,Sequence<values...>>::type type;
};
template<typename Func> struct Filter<Func,Sequence<>> { typedef Sequence<> type; };
struct IsEven {
template<int n> struct Eval { enum{ value = !(n%2) }; };
};
template<typename Func,typename Seq> struct Map;
template<typename Func,int first, int... values>
struct Map<Func, Sequence<first,values...>>
{
typedef Sequence<values...> Tail;
typedef typename Map<Func,Tail>::type TailMapped;
enum { firstMapped = Func::template Eval<first>::value };
typedef typename Prepend<TailMapped,firstMapped>::type type;
};
template<typename Func>
struct Map<Func,Sequence<>>
{
typedef Sequence<> type;
};
template<int begin, int end>
struct generate_sequence
{
template<int current, int... values>
struct helper: helper<current-1, current-1, values...> {};
template<int... values>
struct helper<begin, values...>
{
typedef Sequence<values...> type;
};
typedef typename helper<end>::type type;
};
template<typename Seq> struct Sum;
template<int first, int... values> struct Sum<Sequence<first, values...>> { enum {value = first + Sum<Sequence<values...>>::value}; };
template<> struct Sum<Sequence<>> { enum {value = 0}; };
template<typename Seq1, typename Seq2=Sequence<>>
struct Reverse { typedef Seq2 type; };
template<int first, int... values, typename Seq2>
struct Reverse<Sequence<first,values...>, Seq2>:Reverse<Sequence<values...>, typename Prepend<Seq2,first>::type> {};
template<typename Seq, char sep=','> struct PrintHelper;
template<int first, int second, int... values, char sep> struct PrintHelper<Sequence<first,second,values...>, sep>:PrintHelper<Sequence<second,values...>, sep>
{
PrintHelper() { std::cout << sep << first; }
};
template<int last, char sep> struct PrintHelper<Sequence<last>, sep>:PrintHelper<Sequence<>, sep>
{
PrintHelper() { std::cout << last; }
};
template<char sep> struct PrintHelper<Sequence<>,sep> { PrintHelper() {} void Do() const {} };
template<typename Seq, char sep=','> struct Print: PrintHelper< typename Reverse<Seq>::type, sep >
{};
typedef typename generate_sequence<0, 10>::type ZeroTo9;
typedef typename Map<SpecificFib,ZeroTo9>::type First10Fibs;
typedef typename Filter<IsEven,First10Fibs>::type First10FibsThatAreEven;
template<typename Sequence>
void PrintSomeInfo( std::string const& name )
{
std::cout << name << " {";
Print<Sequence>();
std::cout << "} sums to " << Sum<Sequence>::value << "\n";
}
int main()
{
PrintSomeInfo<ZeroTo9>("Zero to 9");
PrintSomeInfo<First10Fibs>("First 10 fibs");
PrintSomeInfo<First10FibsThatAreEven>("First 10 fibs that are even");
}
I hope that helps.
What I am doing above is playing around with template programming. I'm deducing the answer using the rather over powered C++ type system, such that if a compiler properly compiled Sum<Sequence>::value, it would be a single compile-time value.
Technically, this is an answer to your question written in C++. As a bonus, it will have O(1) run time. :)
...
More seriously. You need to solve your problem one step at a time.
Write a program that outputs the first 10 elements of the sequence. I would say "like the above", but you should do it in a way you understand.
Let's analyze your code step by step and see where you're going wrong:
//ANSWER = 4613732
int max = 4000000;
int n;
int sum;
for(n=0; n<=max;)
{
Let's stop right here... what does this loop do? It loops starting from 0, until n is equal to 4000001. The problem description asks you to sum the even Fibonacci terms that do not exceed 4000000. So you are, essentially, treating n as a variable that stores a Fibonacci number. OK...
while(n%2 == 0)
{
Now what does this code do? It loops while n is even. Why would you want to do that?
n = (n-1)+(n-2);
OK. So what does this calculate? It sorta, kinda looks like something that would calculate a Fibonacci number. But does it? Let's check! You start with n = 0. Notice that 0 % 2 == 0 so you would execute this code, which would set n to: (0 - 1) + (0 - 2) = 0 - 1 + 0 - 2 = -3. The loop would then exit, since -3 is not an even number.
But... wait, -3 is not a Fibonacci number!
Remember, a Fibonacci number, let's call it F(n), is defined with the following formula: F(n) = F(n - 1) + F(n - 2), with special cases for F(0) = 0 and F(1) = 1. In other words a Fibonacci number is the sum of the previous two Fibonacci numbers.
So now, does the expression you wrote calculate Fibonacci numbers?
By the way, at this point you should be able to see why this code just run and run and run and run... If not, remember what n is and check the for loop. What will happen?
I am going to give you the answer; it's probably a little too complicated, but if you take the time to step through it ON PAPER and work it like the computer would, following each step line by line, you will see how it works and gain a better understand of C and C++ and how to translate algorithms and mathematical concepts into code.
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
// We store the last 2 Fibonacci numbers that we calculated in this
// small array to improve the performance of our routine and avoid
// having to recalculate things all the time. We update it as we go
// and initialize it with the values for fib(0) and fib(1)
int max = 4000000, ans = 4613732, sum = 0, lfi = 0, lfn = 1;
int lastfibs[2] = { 0, 1 };
do
{
// Calculate the next fibonacci number in the sequence
lfn = lastfibs[0] + lastfibs[1];
// And store it in our cache, updating the cache index
lastfibs[lfi++] = lfn;
if(lfi == 2) // "round and round you're turning me..."
lfi = 0;
if((lfn & 1) == 0) // An even Fibonacci number! Add it to the sum
sum += lfn;
} while(lfn <= max);
if(sum != ans)
cout << "BOO! The sum is " << sum << " but it's supposed to be " << ans << "!" << endl;
else
cout << "Yay! The sum is " << sum << "! Thanks StackOverflow!" << endl;
return 0;
}
I hope that it helps you think about the problem and come up with your own solution.
bool Ctest::fibonacci(int *fibo, int length)
{
int m = 2, n =1,d,q;
int flag;
if(fibo[0]==0 && fibo[1]==1 && fibo[3]==1)
flag = 1;
for(int i =3; i<length; i++)
{
if(fibo[i] == m)
{
flag = 1;
}
else
{
flag = 0;
}
d = m;
q = m+n;
m=q;
n=d;
}
if (flag == 0)
{
return TRUE;
}
else
return FALSE;
}
x = 1;
y = 1;
sum = 0;
a = 0;
while ( x < 4000 ) {
if ( (x % 2) == 0 ){
a = x + a;
}
print "x\n";
sum = x + y;
x = y;
y = sum;
}
print "\na\n";
boom
I have:
const char kLetters[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
I can call kLetters[n] to obtain the nth letter of the Keyboard alphabet in O(1) time. However I will have to iterate through kLetter (taking O(n) or at least O(log n) ) time for the reverse lookup.
I would like to create a reverse lookup table as a compile-time static lookup table using templates and was wondering if there is a ways of doing this.
EDIT - as mentioned in the comments, a reverse lookup would mean I supply 'E' and get back 2. Also my alphabet example was not the best example, I would like to make no assumptions about the order. For that reason I have change the alphabet to keyboard order.
How about something like this? It lets you specify the range rather than a complete string.
#include <iostream>
template <int Start, int End, int N>
struct lookup {
static_assert(Start != End, "Can't have 0 length lookup table");
enum { value = lookup<Start+(Start < End ? 1:-1),End,N-1>::value };
};
template <int Start, int End>
struct lookup<Start,End,0> {
enum { value = Start };
};
template <int Start, int End, int V, int P=0>
struct reverse_lookup {
static_assert(Start != End, "V isn't in the range Start, End");
static_assert(Start != End || !P, "Can't have 0 length range");
enum { value = reverse_lookup<Start+(Start < End ? 1:-1),End,V,P+1>::value };
};
template <int Start, int End, int P>
struct reverse_lookup<Start,End,Start,P> {
enum { value = P };
};
int main() {
std::cout << char(lookup<'A', 'Z', 3>::value) << std::endl;
std::cout << char(lookup<'Z', 'A', 3>::value) << std::endl;
std::cout << int(reverse_lookup<'A','Z','F'>::value) << std::endl;
}
Alright, after knowing what reverse lookup is, I think you can do this:
const char kLetters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int get_index(char letter)
{
return letter - 'A';
}
After all, the letter A is at index 0, B at 1, C at 2... and so on. That gives enough hint.
My O(1) solution.
So far other solutions work for non-arbitrary sequence of letters, and #awoodland solution assumes that the letter whose index is to be obtainted is known at compile time which makes it less useful.
But this solution has attempted to solve both limitations; that is, it should work:
With arbitrary sequence of letters, such as
const char Letters[] = "ZBADCEWFVGHIUXJTKSLYQMROPN";
And the letters may be unknown at compile time. The function that gets the index has this signature:
int Index(char letter);
Here is the complete code which uses a technique described by # David RodrÃguez in his blog:
#include <iostream>
const char Letters[] = "ZBADCEWFVGHIUXJTKSLYQMROPN";
template<char L> int Index();
template<> int Index<'Z'>() { return 0; }
template<> int Index<'B'>() { return 1; }
template<> int Index<'A'>() { return 2; }
template<> int Index<'D'>() { return 3; }
template<> int Index<'C'>() { return 4; }
template<> int Index<'E'>() { return 5; }
template<> int Index<'W'>() { return 6; }
template<> int Index<'F'>() { return 7; }
template<> int Index<'V'>() { return 8; }
template<> int Index<'G'>() { return 9; }
template<> int Index<'H'>() { return 10; }
template<> int Index<'I'>() { return 11; }
template<> int Index<'U'>() { return 12; }
template<> int Index<'X'>() { return 13; }
template<> int Index<'J'>() { return 14; }
template<> int Index<'T'>() { return 15; }
template<> int Index<'K'>() { return 16; }
template<> int Index<'S'>() { return 17; }
template<> int Index<'L'>() { return 18; }
template<> int Index<'Y'>() { return 19; }
template<> int Index<'Q'>() { return 20; }
template<> int Index<'M'>() { return 21; }
template<> int Index<'R'>() { return 22; }
template<> int Index<'O'>() { return 23; }
template<> int Index<'P'>() { return 24; }
template<> int Index<'N'>() { return 25; }
typedef int (*fptr)();
const int limit = 26;
fptr indexLookup[ limit ];
template <char L>
struct init_indexLookup {
static void init( fptr *indexLookup ) {
indexLookup[ L - 'A' ] = &Index<L>;
init_indexLookup<L-1>::init( indexLookup );
}
};
template <>
struct init_indexLookup<'A'> {
static void init( fptr *indexLookup ) {
indexLookup[ 0 ] = &Index<'A'>;
}
};
const int ignore = (init_indexLookup<'Z'>::init(indexLookup),0);
int Index(char letter)
{
return indexLookup[letter-'A']();
}
And here is the test code:
int main()
{
std::cout << Index('A') << std::endl;
std::cout << Index('Z') << std::endl;
std::cout << Index('B') << std::endl;
std::cout << Index('K') << std::endl;
}
Output:
2
0
1
16
Online demo : http://ideone.com/uzE2t
Well, that actually is two function calls: one to Index(), other to from one in the indexLookup. You can easily avoid first function call by writing (ideone):
int main()
{
std::cout << indexLookup['A'-'A']() << std::endl;
std::cout << indexLookup['Z'-'A']() << std::endl;
std::cout << indexLookup['B'-'A']() << std::endl;
std::cout << indexLookup['K'-'A']() << std::endl;
}
That looks cumbersome, but hey, we can make Index() inline:
inline int Index(char letter)
{
return indexLookup[letter-'A']();
}
That looks fine, and most likely now compiler will make it equivalent to one function call!
Simple yet O(1) solution
Wait. I just realized that the whole solution reduces to a lookup table which is initialized as:
const int indexLookup[] = {2,1,4,3,5,7,9,10,11,14,16,18,21,
25,23,24,20,22,17,15,12,8,6,13,19,0};
inline int Index(char letter)
{
return indexLookup[letter-'A'];
}
which looks unbelievably simple!
If you can use Boost and only need compile-time lookups:
using namespace boost::mpl;
typedef vector_c<char, 'A', 'B', 'C', 'D'> Chars;
// lookup by index:
std::cout << at_c<Chars, 1>::type::value << std::endl; // B
// lookup by value:
typedef find<Chars, integral_c<char, 'C'> >::type Iter;
std::cout << Iter::pos::value << std::endl; // 2
This assumes that 'Z' > 'A', but does not assume letters are contiguous. (Though it takes less memory if they are) I was tempted to put in if (numrLetters>26) conditionals so a smart compiler could use addition rather than the tables for ASCII, but then decided I didn't want to slow the code in the case of less-smart compilers.
const char kLetters[] = "ABCDEFGHJJKLMNOPQRSTUVWXYZ";
const int numLetters = sizeof(kLetters);
const char rkLetters['Z'-'A'] = {};
const int numrLetters = sizeof(rkLetters);
struct LetterInit {
LetterInit() {
for(int i=0; i<numLetters; ++i)
rkLetters[kLetters[i]-'A'] = i;
}
}LetterInitInst;
char findChar(int index) {
assert(index>=0 && index<numLetters);
return kLetters[index];
}
int findIndex(char letter) {
assert(letter>='A' && letter<='Z');
return rkLetters[letter-'A'];
}
As there are several solutions given that don't generate a table but still allow compile time lookup, here is another one
constexpr char kLetters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
constexpr int get(char const x, int const i = 0) {
return kLetters[i] == x ? i : get(x, i + 1);
}
Use at compile time
int x[get('F')];
static_assert(sizeof(x) == sizeof(int[5]), "");
Specifying a character that doesn't exist will result in an error. If you use the function at runtime, you will get undefined behavior if you specify a character that doesn't exist. Proper checking can be added for those cases.
It yields the index of the first character found. No error is given if a character appears twice in the haystack.
If you can use c++0x (tested with gcc 4.5), this works:
#include<initializer_list>
#include<iostream>
#include<map>
constexpr int getLetterNumber(char a){ return std::map<char,int>({{'a',2},{'b',1},{'c',4}})[a]; }
int main(){
const char ch='b';
std::cout<<ch<<": "<<getLetterNumber(ch)<<std::endl;
}
constexpr enforces evaluation at compile-time.
EDIT: that solution is not correct, as pointed out. constexpr does not enfoce compile-time evaluation. This does does the lookup really at compile-time (similar to solutions posted meanwhile).
#include<iostream>
template<char C> int ch2Num();
#define CHR(c,i) template<> int ch2Num<c>(){ return i; }
CHR('a',2); CHR('b',1); /* ... */
#undef CHR
int main(void){
const char ch='b';
std::cout<<ch<<": "<<ch2Num<ch>()<<std::endl;
};