Warum wird diese Formel in der Literatur zur tabellenbasierten Sin-Approximation immer verwendet, wenn eine andere Formel sinnvoller zu sein scheint?

Die Literatur zur Berechnung der Elementarfunktionsin mit Tabellen bezieht sich auf die Formel:

sin(x) = sin(Cn) * cos(h) + cos(Cn) * sin(h)

wox = Cn + h, Cn ist eine Konstante für diesin(Cn) undcos(Cn) wurden vorberechnet und sind in einer Tabelle verfügbar, und wenn Gal's Methode folgt,Cn wurde so gewählt, dass beidesin(Cn) undcos(Cn) werden durch Gleitkommazahlen genau angenähert. Die Quantitäth liegt in der Nähe0.0. Ein Beispiel für die Bezugnahme auf diese Formel ist diesArtikel (Seite 7).

Ich verstehe nicht, warum das Sinn macht:cos(h), jedoch wird es berechnet, wird wahrscheinlich um mindestens 0,5 ULP für einige Werte von falsch seinhund da ist es nah dran1.0Dies scheint drastische Auswirkungen auf die Genauigkeit des Ergebnisses zu habensin(x) wenn auf diese Weise berechnet.

Ich verstehe nicht, warum die unten stehende Formel stattdessen nicht verwendet wird:

sin(x) = sin(Cn) + (sin(Cn) * (cos(h) - 1.0) + cos(Cn) * sin(h))

Dann die beiden Größen(cos(h) - 1.0) undsin(h) können mit Polynomen approximiert werden, die einfach zu präzisieren sind, da sie Ergebnisse nahe Null liefern. Die Werte fürsin(Cn) * (cos(h) - 1.0), cos(Cn) * sin(h) und weil ihre Summe noch klein ist und ihre absolute Genauigkeit in ULPs der kleinen Menge ausgedrückt wird, die die Summe darstellt, so dass diese Menge addiert wirdsin(Cn) ist fast richtig gerundet.

Fehlt mir etwas, das das frühere, populäre und einfachere Verhalten der Formel ebenfalls verbessert? Gehen die Autoren davon aus, dass die Leser verstehen, dass die erste Formel tatsächlich als zweite Formel implementiert ist?

EDIT: Beispiel

Eine Tabelle mit einfacher Genauigkeit zur Berechnung der einfachen Genauigkeitsinf() undcosf() könnte den folgenden Punkt in einfacher Genauigkeit enthalten:

         f             |        cos f          |       sin f      
-----------------------+-----------------------+---------------------
0.017967 0x1.2660bcp-6 |    0x1.ffead8p-1      |    0x1.265caep-6
                       |    (actual value:)    |    (actual value:)
                       | ~0x1.ffead8000715dp-1 | ~0x1.265cae000e6f9p-6

Die folgenden Funktionen sind spezialisierte Funktionen mit einfacher Genauigkeit0.017967:

float sinf_trad(float x)
{
  float h = x - 0x1.2660bcp-6f;

  return 0x1.265caep-6f * cos_0(h) + 0x1.ffead8p-1f * sin_0(h);
}

float sinf_new(float x)
{
  float h = x - 0x1.2660bcp-6f;

  return 0x1.265caep-6f + (0x1.265caep-6f * cosm1_0(h) + 0x1.ffead8p-1f * sin_0(h));
}

Das Testen dieser Funktionen zwischen 0,01f und 0,025f scheint zu zeigen, dass die neue Formel genauere Ergebnisse liefert:

$ gcc -std=c99 test.c && ./a.out 
relative error, traditional: 2.169624e-07, new: 1.288049e-07
sum of squares of absolute error, traditional: 6.616202e-12, new: 2.522784e-12

Ich habe mehrere Verknüpfungen verwendet, schauen Sie sich das andas komplette Programm.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage