Hi, 1000-1999 Nullen... Respekt... Ich denke jetzt mal dass das ein Irrtum ist.
Wie wärs mit float? Aber Achtung: Floats nur wenn umbedingt nötig, denn die verbrauchen irrsinnig Speicherplatz. (Flash wie Ram!)
Hallo Leute,
ich möchte in C eine Formel der Form:
y = 10 ^ x + z
... in reiner Integerarithmetik umsetzen. Dabei ist x ein komplexerer Ausdruck mit dem Ergebnis 1,000 bis 1,999.
Natürlich möchte ich das möglichst genau umsetzen, also am liebsten x um den Faktor 1000 hochsetzen (x = 1000 ... 1999). Das kriege ich auch hin.
Wie muss ich (als Mensch mit nur geringen Mathe-Kenntnissen) aber die Potenzfunktion (10 ^ x) oder die Gesamtformel verändern, um wieder auf ein korrektes Ergebnis für y zu kommen?
Gruß Dirk
Hi, 1000-1999 Nullen... Respekt... Ich denke jetzt mal dass das ein Irrtum ist.
Wie wärs mit float? Aber Achtung: Floats nur wenn umbedingt nötig, denn die verbrauchen irrsinnig Speicherplatz. (Flash wie Ram!)
das geht z.b. mit ner reihenentwicklung (macht man mit z.b. maple)
zuerst betrachten wir nur mal
y=10^x
wenn du x mit 1000 multiplizierst (um integerwerte zu haben)
dann lautet die neue formel:
y=10^(x/1000)
davon macht man (z.b.) ne taylorentwicklung mit entwicklungspunkt 1000:
y=10.+(0.2302585093e-1)*(x-1000.)+(0.2650949056e-4)*(x-1000.)^2+(0.2034678592e-7)*(x-1000.)^3+(0.1171255149e-10)*(x-1000.)^4+(0.5393829291e-14)*(x-1000.)^5
in dieser formel hast du nun nur noch additionen und multiplikationen.
da die koeffizienten jedoch sehr klein sind, muss auch das ergebnis erst mal in nen anderen bereich skaliert werden.
d.h. wir berechnen (z.b.) erst mal:
y=100000*10^(x/1000)
dazu müssen wir die koeffizienten einfach mit 100000 multiplizieren:
y=1000000+2303*(x-1000.)+3*(x-1000.)^2
jetzt hat man also ne reine integeroperation.
wie man sieht, ist das eigentlich einfach ne quadratische aproximation der gewünschten funktion und damit recht ungenau. trotzdem muss man mit recht großen intergerzahlen arbeiten.
für eine bessere aproximation muss man entweder noch größere integerzahlen verwenden, damit man höhere terme der taylorentwicklung verwenden kann.
oder man muss ne andere reihenentwicklung verwenden (da must du dann aber jemanden fragen, der sich etwas besser damit auskennt).
eine gänzlich andere methode besteht darin, einfach ne tabelle mit den 1000 werten zu berechnen und fest (in nem array) zu speichern:
z.b. y(1.234)=feld[234];
das dürfte am einfachsten und genauesten sein, braucht aber entsprechend platz.
den platzbedarf kann man zu lasten der genauigkeit reduzieren, indem man anstatt 1000 werten nur 100 speichert und dazwischen linear (oder quadratisch) interpoliert.
(ps. hoffe ich hab mich nicht verrechnet, aber das merkst du dann schon beim ausprobieren)
@s.o.
denk lieber noch mal nach, worum es hier geht
Geht's eigentlich um's Prinzip oder hast du andere Gründe, das mit integern machen zu wollen ?
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
ps. anstatt mit 10er potenzen zu multiplizieren bietet es sich an, lieber 2er potenzen zu nehmen. also z.b. anstatt 1000 besser 1024. dann ist die multiplikation (und die spätere division) einfach ein verschieben von bits (viel einfacher als ne echte multiplikation)
Es gibt da noch eine alternative zur Potenzreihenentwicklung.
Man schreibt 10^(x/1000) als (10^(1/1000))^x. Die tausensendste Wurzel aus 10 kann man vorher berechnen. Mit echten interger Zahlen geht das natürlich nicht, sondern mit festkomma Zahlen.
Die Potenz ^x geht relativ schnell durch wiederhohltes quadrieren und Multiplizieren. ggf. kann auch eine Tabelle mit 10^(1/1000),10^(2/1000),10^(4/1000),10^(8/1000),...,10^(1024/1000) usw. anlegen und nur noch entsperechend der Bits in X die Werte aus der Tabelle multiplizieren.
Hallo Leute,
danke für die guten Tips!
Ich möchte in einem Tiny möglichst sparsam mit dem Speicherplatz haushalten, daher der Versuch einer Integer-Arithmetik und Verzicht auf float.
Einen gewissen Charme hätte ja das Anlegen einer Tabelle, aber mein x ist ja ein Ausdruck mit weiteren Variablen, die auch noch von Meßwerten abhängen. Damit kann ich das nicht umsetzen ... und es würde ja auch wieder viel Platz wegnehmen.
Ich werde es wohl doch 'mal mit float probieren.
Gruß Dirk
Lesezeichen