Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CW_Kovok

Alter Hase

  • »CW_Kovok« ist der Autor dieses Themas

Beiträge: 836

Wohnort: nähe Bonn

Beruf: Schüler

  • Private Nachricht senden

11

20.02.2006, 17:29

so habe jetzt mal deine taylorformel in leicht veränderter form implementiert:

C-/C++-Quelltext

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <ctime>
#include <cmath>

using namespace std;

float FastSin0(const float& fAngle)
{
    float fASqr = fAngle*fAngle;
    float fResult = 7.61e-03f;
    fResult *= fASqr;
    fResult -= 1.6605e-01f;
    fResult *= fASqr;
    fResult += 1.0f;
    fResult *= fAngle;
    return fResult;
}

float FastSin1(const float& fAngle)
{
    float fASqr = fAngle*fAngle;
    float fResult = -2.39e-08;

    fResult *= fASqr;
    fResult += 2.7526e-06f;
    fResult *= fASqr;
    fResult -= 1.98409e-04f;
    fResult *= fASqr;
    fResult += 8.3333315e-03f;
    fResult *= fASqr;
    fResult -= 1.666666664e-01f;
    fResult *= fASqr;
    fResult += 1.0f;
    fResult *= fAngle;

    return fResult;
}

int fak(int n)
{
    int x=1;
    while(n>1)
    {
        x*=n;
        n--;
    }

    return x;
}

float TnSin(float x, unsigned short n)
{
    float Tn = 0;
    for (unsigned short k = 0; k<n; k++)
    {
        if(k%2)
            Tn += (-1.0f / fak(k)) * pow(x, k);
        else
            Tn += (1.0f / fak(k)) * pow(x, k);
    }
    return Tn;
}

int main(void)
{
    long start, ende;
    float a1, a2, a3, a4, a5;

    float pi = atan(1.0f)*2.0f; //da nur halbes pi korrekt


    start = clock();
    
    for(float i=0.0f; i<pi; i=i+0.000001f)
        FastSin0(i);

    ende = clock();

    a1 = float(ende-start);
    cout<<"FastSin0 fertig"<<endl;

    start = clock();
    
    for(float i=0.0f; i<pi; i=i+0.000001f)
        FastSin1(i);

    ende = clock();

    a2 = float(ende-start);
    cout<<"FastSin1 fertig"<<endl;

    start = clock();
    
    for(float i=0.0f; i<pi; i=i+0.000001f)
        sinf(i);

    ende = clock();

    a3 = float(ende-start);
    cout<<"sinf fertig"<<endl;

    start = clock();
    
    for(float i=0.0f; i<pi; i=i+0.000001f)
        sin(i);

    ende = clock();

    a4 = float(ende-start);
    cout<<"sin fertig"<<endl;

    start = clock();
    
    for(float i=0.0f; i<pi; i=i+0.000001f)
        TnSin(i, 5);

    ende = clock();

    a5 = float(ende-start);
    cout<<"TnSin fertig"<<endl;

    cout<<"sinf: "<<a3/CLOCKS_PER_SEC<<" entspricht: "<<a3/a3*100<<"%"<<endl;
    cout<<"sin: "<<a4/CLOCKS_PER_SEC<<" entspricht: "<<a3/a4*100<<"%"<<endl;
    cout<<"FastSin0: "<<a2/CLOCKS_PER_SEC<<" entspricht: "<<a3/a1*100<<"%"<<endl;
    cout<<"FastSin1: "<<a1/CLOCKS_PER_SEC<<" entspricht: "<<a3/a2*100<<"%"<<endl;
    cout<<"TnSin(unoptimiert): "<<a5/CLOCKS_PER_SEC<<" entspricht: "<<a3/a5*100<<"%"<<endl;

    return 0;
}
Ergebnis:

Zitat

FastSin0 fertig
FastSin1 fertig
sinf fertig
sin fertig
TnSin fertig
sinf: 0.172 entspricht: 100%
sin: 0.219 entspricht: 78.5388%
FastSin0: 0.234 entspricht: 137.6%
FastSin1: 0.125 entspricht: 73.5043%
TnSin(unoptimiert): 1.531 entspricht: 11.2345%
Drücken Sie eine beliebige Taste . . .

Selbst nach ungenauen 5 iterationen ist er bereits sehr viel langsamer, oder fällt dir irgendeine verbesserung ein? Mir fällt nix ein außer statt der Schleife die 5 schritte hintereinader zu schreiben und die Fakultäten vorzuberechnen, habe hier noch nen ansatz gefunden:
http://de.wikipedia.org/wiki/Sinus da gibt es sone Produktentwicklung, währe das ne idee? Oder ist das nicht genau das was die fastSin funktionen tun?[/quote]
Was es alles gibt, das ich nich brauche - Aristoteles

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

12

20.02.2006, 17:38

Fakultäten vorberechnen ist sicher nich verkehrt, aber die schritte hintereinander zu schreiben wird nix bringen, denk ich. 5 Iterationen sind sicherlich immer noch auf einige Stellen hinterm Komma genau. Deine FastSin0 macht ja auch nur 3 Schritte.

was du da mit Tn gemacht hast ist übrigens falsch, weil du jetzt abwechseln 1 und -1 nimmst, aber du müsstest ja jeden 2. Schritt dann auslassen.

Bau doch mal noch einen Genauigkeitsvergleich ein, wäre auch interessant.

CW_Kovok

Alter Hase

  • »CW_Kovok« ist der Autor dieses Themas

Beiträge: 836

Wohnort: nähe Bonn

Beruf: Schüler

  • Private Nachricht senden

13

20.02.2006, 18:45

so hier neuestes ergebnis, jetzt folgt noch eine genauigkeitsanalyse:

C-/C++-Quelltext

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <iostream>
#include <ctime>
#include <cmath>

float pi = atan(1.0f)*2.0f; //da nur halbes pi korrekt


using namespace std;

float FastSin0(const float& fAngle)
{
    float fASqr = fAngle*fAngle;
    float fResult = 7.61e-03f;
    
    fResult *= fASqr;
    fResult -= 1.6605e-01f;
    fResult *= fASqr;
    fResult += 1.0f;
    fResult *= fAngle;
    return fResult;
}

float FastSin1(const float& fAngle)
{
    float fASqr = fAngle*fAngle;
    float fResult = -2.39e-08;

    fResult *= fASqr;
    fResult += 2.7526e-06f;
    fResult *= fASqr;
    fResult -= 1.98409e-04f;
    fResult *= fASqr;
    fResult += 8.3333315e-03f;
    fResult *= fASqr;
    fResult -= 1.666666664e-01f;
    fResult *= fASqr;
    fResult += 1.0f;
    fResult *= fAngle;

    return fResult;
}

float TnSin(float x)
{
    float tri = x*x*x;

    float Tn = 1.0f*x;
    Tn -= 1.0f/6.0f * tri;
    Tn += 1.0f/120.0f * tri * x * x;
    Tn -= 1.0f/5040.0f * tri * tri * x;

    return Tn;
}

int main(void)
{
    long start, ende;
    float a1, a2, a3, a4, a5;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            FastSin0(i);

    ende = clock();

    a1 = float(ende-start);
    cout<<"FastSin0 fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            FastSin1(i);

    ende = clock();

    a2 = float(ende-start);
    cout<<"FastSin1 fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            sinf(i);

    ende = clock();

    a3 = float(ende-start);
    cout<<"sinf fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            sin(i);

    ende = clock();

    a4 = float(ende-start);
    cout<<"sin fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            TnSin(i);

    ende = clock();

    a5 = float(ende-start);
    cout<<"TnSin fertig"<<endl;

    start = clock();
    
    cout<<"sinf: "<<a3/CLOCKS_PER_SEC<<" entspricht: "<<a3/a3*100<<"%"<<endl;
    cout<<"sin: "<<a4/CLOCKS_PER_SEC<<" entspricht: "<<a3/a4*100<<"%"<<endl;
    cout<<"FastSin0: "<<a2/CLOCKS_PER_SEC<<" entspricht: "<<a3/a1*100<<"%"<<endl;
    cout<<"FastSin1: "<<a1/CLOCKS_PER_SEC<<" entspricht: "<<a3/a2*100<<"%"<<endl;
    cout<<"TnSin: "<<a5/CLOCKS_PER_SEC<<" entspricht: "<<a3/a5*100<<"%"<<endl;
   
    return 0;
}
Ergibt das Ergebnis:

Zitat

FastSin0 fertig
FastSin1 fertig
sinf fertig
sin fertig
TnSin fertig
sinf: 1.656 entspricht: 100%
sin: 2.218 entspricht: 74.6619%
FastSin0: 2.078 entspricht: 121.765%
FastSin1: 1.36 entspricht: 79.692%
TnSin: 1.125 entspricht: 147.2%
Drücken Sie eine beliebige Taste . . .

sieht doch schon ganz gut aus oder?
Was es alles gibt, das ich nich brauche - Aristoteles

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

14

20.02.2006, 18:59

ja sieht sehr gut aus, schade nur, dass das Taylorpolynom jetzt nicht mehr dynamisch ist.. Aber der Geschwindigkeitsgewinn ist natürlich ernorm. Bin sehr auf die Genauigkeiten gespannt.

CW_Kovok

Alter Hase

  • »CW_Kovok« ist der Autor dieses Themas

Beiträge: 836

Wohnort: nähe Bonn

Beruf: Schüler

  • Private Nachricht senden

15

20.02.2006, 19:04

so habe noch eins bei der taylorentwicklung dran gehängt:

C-/C++-Quelltext

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <iostream>
#include <ctime>
#include <cmath>

float pi = atan(1.0f)*2.0f; //da nur halbes pi korrekt


using namespace std;

inline float FastSin0(const float& fAngle)
{
    float fASqr = fAngle*fAngle;
    float fResult = 7.61e-03f;
    
    fResult *= fASqr;
    fResult -= 1.6605e-01f;
    fResult *= fASqr;
    fResult += 1.0f;
    fResult *= fAngle;
    return fResult;
}

inline float FastSin1(const float& fAngle)
{
    float fASqr = fAngle*fAngle;
    float fResult = -2.39e-08;

    fResult *= fASqr;
    fResult += 2.7526e-06f;
    fResult *= fASqr;
    fResult -= 1.98409e-04f;
    fResult *= fASqr;
    fResult += 8.3333315e-03f;
    fResult *= fASqr;
    fResult -= 1.666666664e-01f;
    fResult *= fASqr;
    fResult += 1.0f;
    fResult *= fAngle;

    return fResult;
}

inline float TnSin(const float& x)
{
    float tri = x*x*x;

    float Tn = 1.0f*x;
    Tn -= 1.0f/6.0f * tri;
    Tn += 1.0f/120.0f * tri * x * x;
    Tn -= 1.0f/5040.0f * tri * tri * x;
    Tn += 1.0f/362880.0f * tri * tri * tri;

    return Tn;
}

int main(void)
{
    long start, ende;
    float a1, a2, a3, a4, a5;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            FastSin0(i);

    ende = clock();

    a1 = float(ende-start);
    cout<<"FastSin0 fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            FastSin1(i);

    ende = clock();

    a2 = float(ende-start);
    cout<<"FastSin1 fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            sinf(i);

    ende = clock();

    a3 = float(ende-start);
    cout<<"sinf fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            sin(i);

    ende = clock();

    a4 = float(ende-start);
    cout<<"sin fertig"<<endl;

    start = clock();
    
    for(int j=0; j<1e3; j++)
        for(float i=0.0f; i<pi; i=i+0.0001f)
            TnSin(i);

    ende = clock();

    a5 = float(ende-start);
    cout<<"TnSin fertig"<<endl;

    start = clock();
    
    cout<<"sinf: "<<a3/CLOCKS_PER_SEC<<" entspricht: "<<a3/a3*100<<"%"<<endl;
    cout<<"sin: "<<a4/CLOCKS_PER_SEC<<" entspricht: "<<a3/a4*100<<"%"<<endl;
    cout<<"FastSin0: "<<a2/CLOCKS_PER_SEC<<" entspricht: "<<a3/a1*100<<"%"<<endl;
    cout<<"FastSin1: "<<a1/CLOCKS_PER_SEC<<" entspricht: "<<a3/a2*100<<"%"<<endl;
    cout<<"TnSin: "<<a5/CLOCKS_PER_SEC<<" entspricht: "<<a3/a5*100<<"%"<<endl;

    float p = 0.0f;

    for(float i=0.0f; i<pi; i+= 0.0001f)
    {
        float j = sin(i) - TnSin(i);
        if(p<j)
            p = j;
    }

    cout<<scientific<<"Genauigkeit TnSin: "<<p<<endl;
   
    p = 0.0f;

    for(float i=0.0f; i<pi; i+= 0.0001f)
    {
        float j = sin(i) - FastSin0(i);
        if(p<j)
            p = j;
    }

    cout<<"Genauigkeit FastSin0: "<<p<<endl;

    p = 0.0f;

    for(float i=0.0f; i<pi; i+= 0.0001f)
    {
        float j = sin(i) - FastSin1(i);
        if(p<j)
            p = j;
    }

    cout<<"Genauigkeit FastSin1: "<<p<<endl;

    return 0;
}
Ergebnis:

Zitat

FastSin0 fertig
FastSin1 fertig
sinf fertig
sin fertig
TnSin fertig
sinf: 1.578 entspricht: 100%
sin: 2.093 entspricht: 75.3942%
FastSin0: 2.047 entspricht: 118.825%
FastSin1: 1.328 entspricht: 77.0884%
TnSin: 1.313 entspricht: 120.183%
Genauigkeit TnSin: 1.192093e-007
Genauigkeit FastSin0: 1.642108e-004
Genauigkeit FastSin1: 1.192093e-007
Drücken Sie eine beliebige Taste . . .

Interessanterweise sind FastSin1 und TnSin jetzt gleich genau und wir haben immer noch einen geschwindigkeitsgewinn von 20%, bei einem glied weniger waren es noch 40% und genauigkeiten im bereich von FastSin0 also auf 4 Stellen. Die Leute die Assembler können, können ja versuchen den tayloralgorhytmus noch zu beschleunigen, so ist er schonmal sehr gut.
Was es alles gibt, das ich nich brauche - Aristoteles

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

16

20.02.2006, 19:10

Is wirklich sehr interessant! Mal schaun, vielleicht fällt mir ja noch was ein um Taylor zu verbessern.. Assembler kann ich allerdings nich :(

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

17

20.02.2006, 19:26

Mach doch mal Anstatt sin(i) sin(pi) oder sin(0), das sind werte die man kennt, dann kannste noch überprüfen wie nah sin und sinf dran sind.

Und ne Angabe der Durchläufe wäre auch nett, nur so als Sahnehäubchen ;) Würde dafür auch ne Konstante einbaun, dann brauchste das bei Änderungen nich immer x mal zu ändern

PS Schreib doch dem Buchautor mal ne Mail, dass er schummelt wenn er Konstanten benutzt, aber den Tayloralgo mit der Fakultätsfunktion benutzt ;)

CW_Kovok

Alter Hase

  • »CW_Kovok« ist der Autor dieses Themas

Beiträge: 836

Wohnort: nähe Bonn

Beruf: Schüler

  • Private Nachricht senden

18

20.02.2006, 19:41

das problem ist, dass nur an einer stelle zu gucken zu ungenau ist, denn der Fehler variiert. Deßhalb nehme ich ja die sin funktion, da liegt der Fehler unterhalb des floatbereichs.

Die Anzahl der Durchläufe ist ja 10e7 * pi, da ich ja auf 4 stellen genau die werte zwischen 0 und pi abfrage und das 1000 mal.

Der Autor gbt nur die beiden fastsin funktionen an, behauptet jedoch, dass die eine 4 und die andere 2 mal schneller ist als normales sinus, naja wie der getestet hat frage ich mich.
Was es alles gibt, das ich nich brauche - Aristoteles

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

19

20.02.2006, 19:55

Stimmt, daran hatte ich nicht gedacht, dann wäre vielleicht eine min und eine max abweichung interessant. Das Problem ist halt, dass die sin Funktion auch irgendwie approximiert, und damit nicht 100%ig genau ist.

CW_Kovok

Alter Hase

  • »CW_Kovok« ist der Autor dieses Themas

Beiträge: 836

Wohnort: nähe Bonn

Beruf: Schüler

  • Private Nachricht senden

20

20.02.2006, 19:58

jupp aber quasi unwichtig,ich habe übrigens nochetwas schneller werden können, indem ich die konstanten am anfang schonmal vorberechnet habe
Was es alles gibt, das ich nich brauche - Aristoteles

Werbeanzeige