Seite 1 von 1

Unerwartete Ergebnisse von Sin und Cos bei großen Zahlen

Verfasst: 31.01.2021 15:59
von STARGÅTE
Hallo Leute,

könntet ihr mal zum unten hinterlegten Code Stellung nehmen?
Unerwarteter weise "schleusen" die Funktionen Sin und Cos den Eingangswert einfach unbearbeitet durch, wenn die Zahl sehr groß wird (>10^19). Das die Funktionen bei solchen Zahlen kein eindeutiges Ergebnis mehr geben können ist mir durchaus bewusst, da die Zahl 10^19 ja bereits 19 Präzisionsstellen hat, eine 80-bit Zahl der FPU aber nur 19 Stellen erfassen kann. Diese Zahl auf das Intervall -Pi bis Pi zu reduzieren geht also nicht mehr. In der Dokumentation zum FPU-Kommando FSIN steht dieses Verhalten auch so drin, allerdings wird dann der C2-flag gesetzt, um anzuzeigen, dass das Ergebnis eben nicht richtig wird. Sollte PureBasic hier nicht diese Flags dann auch lesen und sinnvollerweise NaN() ausgeben, wie es bei Tan() der Fall ist?

Code: Alles auswählen

Define e.i
Define d.d
Debug RSet("d =", 25) + RSet("Cos(d) =", 25) + RSet("Sin(d) =", 25) + RSet("Tan(d) =", 25)
For e = 0 To 21
	d = Pow(10.0, e)
	Debug RSet("10.0^"+e, 25) + RSet(StrD(Cos(d)), 25) + RSet(StrD(Sin(d)), 25) + RSet(StrD(Tan(d)), 25)
Next

Code: Alles auswählen

                      d =                 Cos(d) =                 Sin(d) =                 Tan(d) =
                   10.0^0             0.5403023059             0.8414709848             1.5574077247
                   10.0^1            -0.8390715291            -0.5440211109             0.6483608275
                   10.0^2             0.8623188723            -0.5063656411            -0.5872139152
                   10.0^3             0.5623790763             0.8268795405             1.4703241557
                   10.0^4            -0.9521553683            -0.3056143889             0.3209711346
                   10.0^5            -0.9993608074              0.035748798             -0.035771663
                   10.0^6             0.9367521275            -0.3499935022             -0.373624454
                   10.0^7            -0.9072703862             0.4205477932            -0.4635308279
                   10.0^8            -0.3633850894             0.9316390271            -2.5637789067
                   10.0^9             0.8378871814             0.5458434494             0.6514522021
                  10.0^10             0.8731196227            -0.4875060251            -0.5583496378
                  10.0^11              0.370847792             0.9286936605             2.5042448154
                  10.0^12             0.7914463026            -0.6112387014            -0.7723059661
                  10.0^13             0.9573637206            -0.2888852825            -0.3017508145
                  10.0^14             -0.977828261            -0.2094084334             0.2141566589
                  10.0^15            -0.5131948427             0.8582721325            -1.6724098939
                  10.0^16            -0.6261782359             0.7796799452            -1.2451406013
                  10.0^17            -0.8854975167            -0.4646441089             0.5247266087
                  10.0^18              0.119650255            -0.9928161041            -8.2976513812
                  10.0^19     10000000000000000000     10000000000000000000                      NaN
                  10.0^20    100000000000000000000    100000000000000000000                      NaN
                  10.0^21   1000000000000000000000   1000000000000000000000                      NaN

Re: Unerwartete Ergebnisse von Sin und Cos bei großen Zahlen

Verfasst: 31.01.2021 22:39
von ccode_new
Hallo STARGÅTE,

und ich dachte eigentlich das PureBasic die Funktionen aus der "math.h"/cmath - nutzt.

Das scheint nicht so zu sein.

Code: Alles auswählen

;C/C++ Funktionen (math.h) ; gcc -lm
ImportC ""
  _sin.d(d.d) As "sin"
  _cos.d(d.d) As "cos"
  _tan.d(d.d) As "tan"
EndImport

Debug Sin(Pow(10, 19))
Debug _sin(Pow(10, 19))

Debug Cos(Pow(10, 19))
Debug _cos(Pow(10, 19))

Debug Tan(Pow(10, 19))
Debug _tan(Pow(10, 19))
Du hast aber Recht:
Die Funktionen Sin() und Cos() sollten NaN zurückgeben.

Alles nach diesen 18 Stellen ist sowieso unsinnig, außer man kann so etwas wie ein echtes "long double"(128bit) nutzen.
C++ Deklaration:
long double sin(long double x);

Ansonsten ist eigentlich die max. Genauigkeit bei einem double 14 Stellen nach dem Komma und bei einem long double (80 bit) 18 Stellen.

Anbei:
Wie berechnet c den Sinus?

Re: Unerwartete Ergebnisse von Sin und Cos bei großen Zahlen

Verfasst: 01.02.2021 01:13
von STARGÅTE
Danke für den Link und die darin enthaltenen weiteren Links, durchaus interessant.

Ich meine klar, wir bzw. ich reden hier ja über eine sehr unübliche Benutzung von Sin und Cos()
und PB muss ja auch gar nicht math.h function nutzen (weiß nicht wie da die Performance ist).
Aber ich denke schon, dass man von dieser Funktion erwarten sollte,
dass sie immer einen Wert zwischen -1.0 und 1.0 ausgibt (wie es im übrigen auch in der Hilfe steht)
und nicht einfach den Eingangswert durchschleust.
Ich weiß nur nicht, ob man sowas jetzt ehr als Bug oder Feature Request posten sollte.

Re: Unerwartete Ergebnisse von Sin und Cos bei großen Zahlen

Verfasst: 01.02.2021 13:32
von ccode_new
Ich wäre für "Feature Request".

Re: Unerwartete Ergebnisse von Sin und Cos bei großen Zahlen

Verfasst: 01.02.2021 13:54
von HeX0R
Naja, wenn es sich nicht so verhält, wie es in der Hilfe steht, ist es ja wohl eher eindeutig ein Bug.

Re: Unerwartete Ergebnisse von Sin und Cos bei großen Zahlen

Verfasst: 01.02.2021 15:35
von NicTheQuick
ccode_new hat geschrieben:Anbei:
Wie berechnet c den Sinus?
Ich habe mich die ganze Zeit gewundert, was ich da eigentlich gerade lese. Das ist ja nur eine Übersetzung des originalen Threads auf Stackoverflow? Also wen die englische Fassung interessiert: https://stackoverflow.com/questions/228 ... -functions