Utwórz statyczną tablicę wartości sin(x) (metaprogramming)

0

Witajcie, nie mogę znaleźć odpowiedzi na pytanie jak mogę stworzyć ww. tablicę :(

Potrafię taką tablicę zrobić dla np wartość = index_w_tablicy, ale nie mam pomysłu na tę funkcję :(

Jesteście w stanie coś doradzić albo wysłać link gdzie znajdę odpowiedź? :3
Z góry dziękuję za pomoc <3

constexpr int TABLE_SIZE = 20;

template <typename VALUETYPE, VALUETYPE INDEX>
struct ValueHelper {
    static constexpr VALUETYPE value = INDEX;
};

template<typename VALUETYPE, int N = 0, VALUETYPE
    ...D>
    struct Helper : Helper<VALUETYPE, N + 1, D...,
    ValueHelper<VALUETYPE, N>::value> { };

template<typename VALUETYPE, VALUETYPE ...D>
struct Helper<VALUETYPE, TABLE_SIZE, D...> {
    static constexpr std::array<VALUETYPE, TABLE_SIZE> table = { D...
    };
};
constexpr std::array<uint16_t, TABLE_SIZE> table = Helper<uint16_t>::table;
5

Opisz dokładniej co chcesz osiągnąć, zamiast przykład rozwiązania, który nie działa.

0

Co niby w nim nie działa? O.o

4

Ok, to jeśli działa, to w czym jest problem? Serio nie rozumiem, widzę kod ale nie wiem co on ma robić (no ok, ma przechowywać wartości funkcji, ale w jakiej dziedzinie, jak rozłożone; a co ważniejsze: co chciałbyś osiągnąć, a nie możesz?)

0

Jak widać ten kod który podałem zachowuje się jak:

tab[0] = 0
tab[1] = 1
tab[2] = 2
...
tab[19] = 19

A chciałbym uzyskać

tab[0] = sin(0)
tab[1] = sin(1)
...

1

Potrafię taką tablicę zrobić dla np wartość = index_w_tablicy, ale nie mam pomysłu na tę funkcję

Bierzesz z biblioteki standardowej funkcję sin, dołączając odpowiedni plik nagłówkowy w razie potrzeby.
Czyli szukasz tego w Google https://www.google.com/search?q=sin+c++
i patrzysz na stronach, który plik musisz dołączyć, żeby zadziałała ci funkcja sin.
Oraz, co ważne, przeczytaj dokładnie dokumentację danej funkcji, bo inaczej nawet jak już znajdziesz funkcję, to ci nie zadziała tak, jak chcesz.

edit: aa, może trochę nie zrozumiałem pytania. Bo ty chcesz, żeby to się generowało za pomocą template'ów? Z drugiej strony moja rada i tak jest valid, bo mam wrażenie, że myślisz, że funkcja sin działa inaczej niż naprawdę, jeśli chcesz ładować do tablicy takie wartości:

tab[0] = sin(0)
tab[1] = sin(1)
2

Problem polega na tym, że funkcje matematyczne używają errno do raportowania błędów.
Tego nie można zmienić, z powodu wstecznej kompatybilności. Niestety efekt jest taki, że te skutki uboczne (side effects) uniemożliwiają uczynienie ich constexpr, ergo nie można ich użyć w wyrażeniach constexpr.
Zapewne to jest powód, dla którego kompilator nie pozwala ci utworzyć tablicy sinusów w czasie kompilacji.

Jakbyś załączył pełen kod (prawie kompilujący się) i/lub przynajmniej wkleił zwartość błędu, zgłaszanego przez kompilator, to byś dostał tę odpowiedź w zasadzie od ręki.

0

Z powodu jw., trzeba też naklepać swojego constexpr sinusa. Ten tutaj → https://codereview.stackexchange.com/questions/133668/constexpr-sin-function-c-14 ← wygląda na działający (nie weryfikowałem), chociaż wbrew temu co mówi nazwa tematu, wymaga C++17, by [] było constexpr.

4

Licz sinus z jego rozwinięcia w szereg Taylora z wybraną dokładnością sin(x) = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \frac{x^9}{9!} \dots

2

Spróbuj użyć fold expresions

#include <iostream>
#include <array>
#include <cmath>
#include <tuple>

using namespace std;

template< size_t... Is >
constexpr array<double,sizeof...(Is)> makeArray(index_sequence<Is...>)
{
    return {{ sin(get<Is>(make_tuple(Is...)))... }};
}

template< size_t N >
constexpr auto makeArray()
{
    return makeArray(make_index_sequence<N>{});
}

template< typename T >
void print( T value ){ cout << value << endl; }

int main()
{
    constexpr auto table = makeArray<10>();
    for( const auto& element : table ) print(element);
}

https://godbolt.org/z/bf9cqKqG4

1 użytkowników online, w tym zalogowanych: 0, gości: 1