Ahoy Hoy. Ich habe einen Integer und möchte davon aber nur einen bestimmten Bereich nutzen. Und überlege ob ich einen nützlichen Befehl übersehen habe. Mein Integer ist sechsstellig und mich interessieren eigentlich nur die höheren drei Stellen. Faktisch kommt es einer Division mit 1000 gleich, wobei ich den Nachkommabereich weglasse. Aber wenn ich nach Division suche, dann kommen immer große Quellcodes die richtige Division können. Brauch ich ja eigentlich nicht, und halte das auch etwas mit Kanonen auf Spatzen geschossen. Gibt es eine Möglichkeit die da einfacher ist? Wenns ein Vektor wäre, wärs ja ziemlich einfach. Habe auch schon überlegt den Integer in einen Bitvektor zu wandeln. Dann wären zwar Teilung durch zwei absolut einfach, aber 10 is dann auch nicht so einfach zu realisieren. Für Tipps Dankbar
Wenn ich dein Problem richtig verstanden habe, kannst du doch den Shift Operator verwenden,oder nicht?
Udo Schmitt schrieb: > 10 Shift left wären eine Division durch 1024. Blödinn, natürlich rechtsshiften , nicht nach links! Sorry für den Fehler.
Stephan J. schrieb: > Wenns ein Vektor wäre, wärs ja ziemlich einfach. Was meinst du, wie ein Integer in der Hardware aussieht? Richtig: das ist ein Vektor. Also müsstest du, falls du VHDL machst, den nur ein wenig konvertieren und casten, und könntest dann die unteren 10 Bits abschneiden für eine Division durch 1024. Wobei das genau genommen nur für unsigned Werte gilt... http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html
Generell gesagt: Eine Division durch eine Konstante läuft immer auf eine Multiplikation mit einem Ganzzahlwert und teilen durch 2^^N hinaus. Je nach Genauigkeit, die Du haben willst, kannst Du mehr oder weniger Aufwand betreiben. X : 1000 kannst Du ereichen mit: * 1, dann /2^^10, Fehler: 2.34% (die von Udo etc. erwähnte Variante) * 131, dann /2^^17, Fehler: 0.05% *2097, dann /2^^21, Fehele: <0.01%
In dem Zusammenhang auch immer ganz nützlich: http://www.synthworks.com/papers/vhdl_math_tricks_mapld_2003.pdf
Lothar Miller schrieb: >> Wenns ein Vektor wäre, wärs ja ziemlich einfach. > Was meinst du, wie ein Integer in der Hardware aussieht? > Richtig: das ist ein Vektor. Das ist mir schon klar. Ich hab ja danach auch noch geschrieben: Habe auch schon überlegt den Integer in einen Bitvektor zu wandeln. Dann wären zwar Teilung durch zwei absolut einfach, aber 10 is dann auch nicht so einfach zu realisieren. --- Aber ich habe dank ein paar guter Tipps folgende Lösung des Problems gefunden, und möchte Leuten, die dasselbe Problem haben, die Lösung nicht vorenthalten. Die 1024 Methode ist ein super Ansatz. Problem war jetzt die Ungenauigkeit der restlichen 24. Bei 360° war das gerade ein Drift von etwa 9° Dies kann man aber durch multiplikation mit einem Korrekturfaktor wieder super ausgleichen. Zur Erläuterung meines Problems und dessen Lösung: Habe bei 360° 64 Inkremente. Macht eine Auflösung von 5,625° pro Inkrement. Benutze einen Inkremente Zähler, und einen Integer Wert von 0..359999, der sich als Produkt von Inkrementalzähler und 5625 zusammensetzt. Wenn ich jetzt durch 1024 teilen würde(Shift 10) würde ich einen Drift erzeugen, der bei 359999 bereits 9° betrifft. Nun brauchen wir nur die Gradgenauigkeit anzupassen. 5,625° * 1,024 ergibt die neue Gradeinteilung von 5,760° pro Inkrement. Den Wertebereich von meinem Integer muss man noch anpassen von 0..359 *1024. Funktioniert einwandfrei. Danke für die Ideen
Stephan J. schrieb: > Das ist mir schon klar. Ich hab ja danach auch noch geschrieben: > Habe auch schon überlegt den Integer in einen > Bitvektor zu wandeln. Dann wären zwar Teilung durch zwei absolut > einfach, aber 10 is dann auch nicht so einfach zu realisieren. Richtig, und deshalb ist es am einfachsten, den Vektor erst mal mit irgendwas mutliplizieren, und dann durch eine Zweierpotenz zu teilen. Peter K. schrieb: > Generell gesagt: Eine Division durch eine Konstante läuft immer auf eine > Multiplikation mit einem Ganzzahlwert und teilen durch 2^^N hinaus. Je > nach Genauigkeit, die Du haben willst, kannst Du mehr oder weniger > Aufwand betreiben. > X : 1000 kannst Du ereichen mit ... Hier mal eine ausführliche Betrachtung des mittleren Falls: Eine Division wie
ist mathematisch das selbe wie
Und geschickterweise wählt man F jetzt so, dass der Wert
nahe an einer Ganzzahl ist. Mit
wird das erreicht:
Damit ist der Fehler nach Abschneiden der Nachkommastellen kleiner als 1/1000. In der VHDL-Praxis sieht die Berechnung also so aus:
1 | ergebnis = wert*131 / 1024; |
Wobei hier die Berechnung mit integer wegen der eingeschränkten Bitbreite evtl. besser durch eine Rechnung mit einem signed oder unsigned Vektor ersetzt wird. Und wenn du sowieso eine ganz andere Skalierung (offenbar in °) willst, dann rechne die Faktoren doch gleich so um, dass nach der Rechnung das Ergebnis gleich in zehntel oder hundertstel Grad herauskommt...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.