Y = ((115*(X-30)) / 2018) +5
Ich ersetze X-30 durch A und konzentriere mich auf den Teil: 115*A / 2018.
Es würde sich wohl nicht lohnen, eine komplette 16 oder 32-Bit Division zu implementieren. Eine andere Methode ist, den Nener so zu verändern, daß er eine Zweierpotenz ist und die Division durch Rechtsschieben zu ersetzen. Dazu erweitere ich den Bruch mit (2048/2018).
Aus der 115 wird 116.7096135.
Y = (116.7096135*(X-30)) / 2048) +5
Da wir hier nur ganze Zahlen verarbeiten können, bedeutet das, daß wir Ersatzweise einen ganzzahligen Faktor nehmen müssen und einen Fehler in Kauf nehmen:
117 / 116.7... =1.00248.. -> Fehler +0.25%
116 / 116.7... =0.993.. -> Fehler -0.61%
Wenn diese Fehler in der Größenordnung inakzeptabel sind, kann man nun Zähler und Nenner (mehrfach) mit 2 malnehmen. Dadurch wird die Anzahl der Stellen im Faktor größer und der Fehler kleiner. Wenn wir mit 32 erweitern bekämen wir:
Y= 3734.707632*A /65536
Bei 3735 hätten wir nur noch einen Fehler von 0.0078 %. Ferner bräuchten wir das Ergebnis nicht einmal durch Rechtsschieben zu teilen, sondern nur die letzten beifden Bytes wegzulassen... Aber leider müßten wir dazu 32-Bit-Arithmetik haben oder implementieren.
Hier würde ich 117 wählen (es sei denn, ein positiver Fehler wäre unzulässig)
Die Binärdarstellung von 117 ist 111 0101.
Die größte "Weite" beim Schieben ist jetzt 6 Stellen.
Wenn ich annehme, daß deine Werte aus einem 11-Bit-A/D-Wandler stammen, sind Werte zwischen 0 und 2047 möglich. Wir haben also nur 5 Stellen Platz, wenn wir mit der 16-Bit-Arithmetik auskommen wollen. Wir lassen daher beim Faktor rechts eine Stelle weg:
111010 und gleich noch eine, denn wenn die rechte Stelle 0 ist, kann man den Bruch durch 2 kürzen: 11101.
Aus
Y = (116.7096135*(X-30)) / 2048) +5
wird:
Y = (29.11740338*(X-30)) / 512) +5
und mit dem ganzzahligen Faktor 29
Y = (29*(X-30)) / 512) +5
29 / 29.117... =0.9939.. -> Fehler -0.61%
Jetzt können wir programmieren:
Code:
L Wert
L 30
+F
T MW50 // Zwischenspeicher X+30
SLW 2
T MW52 // Zwischenspeicher 4*(X+30)
SLW 1
T MW54 // Zwischenspeicher 8*(X+30)
SLW 1
T MW56 // Zwischenspeicher 16*(X+30)
L MW54
+F // akku enthält 24*(X+30)
L MW52
+F // akku enthält 28*(X+30)
L MW50
+F // akku enthält 29*(X+30)
SRW 9 // akku enthält 29*(X+30) / 512
L 5
+F // akku enthält 29*(X+30) / 512+5
T Ergebnis
[/code]