Forum: PC-Programmierung Rundungsalgorithmus gesucht


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Tobias P. (hubertus)


Bewertung
0 lesenswert
nicht lesenswert
Hi, ich habe folgendes Problem:
ich habe in Matlab ein Script gebastelt, welches mir Bauteilwerte für 
eine Schaltung berechnet. So weit so gut. Nun kommen da natürlich 
Kondensatoren von 42.1234pF und Widerstände von 71.37412Ohm und so 
weiter vor - mit den exakten Bauteilwerten ist natürlich auch die 
Performance der Schaltung immer optimal... mich intressiert aber die 
Abweichung, welche ich erhalte, wenn ich für alle Bauteile E12er-Werte 
benutze.
Also müssen nach dem Berechnen der Bauelementwerte diese auf E12 
gerundet werden.
Wie kann man das elegant machen? gibts da einen Algorithmus für?
Ich hab bis jetzt die Holzhammermethode genommen: durch eine Tabelle 
aller E12 iterieren, Fehler berechnen, und dasjenige Element mit dem 
geringsten Fehler dann nehmen.
Aber geht das auch eleganter?
Die E12er Werte kann man ja irgendwie mit der 12. Wurzel aus 10 
berechnen... ?

von Tilo R. (joey5337) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
"Früher" war der Algorithmus ungefähr folgender:
1. Idealwerte berechnen
2. den einen oder anderen Kondensator festlegen. Kondensatoren gibt es 
i. d. Regel nicht in E12, deswegen wird da angefangen.
3. Berechnen und wählen von Widerständen passend zu den bisher gewählten 
Werten.
4. 2 & 3 wiederholen, bis alle Werte festgelegt sind.

Heute kann man natürlich schneller rechnen, insofern ist die 
Holzhammermethode nicht zwingend die schlechteste. Zudem haben alle 
Bauteile Toleranzen, die man so auch simulieren kann.

Das mit der 12. Wurzel ist im Prinzip richtig, die Normreihenwerte sind 
aber auch gerundet.

von Kolja L. (kolja82)


Bewertung
-1 lesenswert
nicht lesenswert
Tobias P. schrieb:
> Aber geht das auch eleganter?

Elegant ist, wenns funktioniert ;-)

von MaWin (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Tobias P. schrieb:
> Die E12er Werte kann man ja irgendwie mit der 12. Wurzel aus 10
> berechnen

Nee, leider nicht, aber die Grenzen zwischen einem Wert und dem nächsten 
könnte man nach 12. Wurzel gestalten, sie liegt dann halt nicht immer in 
der exakten Mitte.

Ich würde plump eine Tabelle nehmen und in ihr suchen, und E6 (für 
Kondensatoren) und E24/48/96 hinzu.

http://www.logwell.com/tech/components/resistor_values.html

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
Tobias P. schrieb:
> ie E12er Werte kann man ja irgendwie mit der 12. Wurzel aus 10
> berechnen.

Um wie viele explizite Werte im Code geht es denn hier? 2 seiten, voll? 
Oder doch nur ... 12? Da ist jede Optimierung vergebens.

Wichtiger ist es, alle Rechnungen auch Mal mit der Kombination aus + und 
- Toleranzen durchlaufen zu lassen, um zu sehen, wo es in der Praxis 
liegen darf und kann.

von Peter M. (r2d3)


Bewertung
0 lesenswert
nicht lesenswert
Tobias P. schrieb:
> Wie kann man das elegant machen? gibts da einen Algorithmus für?
> Ich hab bis jetzt die Holzhammermethode genommen: durch eine Tabelle
> aller E12 iterieren, Fehler berechnen, und dasjenige Element mit dem
> geringsten Fehler dann nehmen.

Iterierst Du über alle E12-Widerstände oder nur über die einer Dekade?

von Hannes J. (Firma: _⌨_) (pnuebergang)


Bewertung
0 lesenswert
nicht lesenswert
Tobias P. schrieb:
> mich intressiert aber die
> Abweichung, welche ich erhalte, wenn ich für alle Bauteile E12er-Werte
> benutze.

Wenn du das rechnen willst, dann ist auf den nächsten passenden Wert 
einer E-Reihe runden nur die halbe Miete. E-Reihen kommen mit 
Toleranzen. Angenommen du rundest deine

> 71.37412Ohm

auf E12 68 Ohm +/- 10% (ich nehme mal an du verwendest den Punkt als 
Dezimaltrenner). Dann liegt ein realer Widerstand mit einer gewissen 
Wahrscheinlichkeitsverteilung zwischen 61,2 ... 74,8 Ohm.

Welche Wahrscheinlichkeitsverteilung? Jetzt wird es übel. Theoretisch 
eine Normalverteilung. Praktisch kann das, aber muss das nicht, ganz 
anders aussehen. Ein Hersteller mag nur die Widerstände aus der 
Produktion, die schlechter als E24, 5% sind, in das E12 Töpfchen 
sortieren. Die anderen verkauft er als E24 oder besser. Dann fehlen alle 
Werte 64,6 ... 74,1 Ohm in der E12 Verteilung. Wenn du von dem 
Hersteller einen E12, 68 Ohm Widerstand kaufst, bekommst du einen mit 
61,2 ... 64,6 Ohm oder einen mit 74,1 ... 74,8 Ohm.

Es sei denn, es besteht eine erhöhte Nachfrage nach E12, dann mag ein 
Hersteller Widerstände aus dem E24-Töpfchen zurück in das E12-Töpfchen 
kippen um genug E12 zum Verkaufen zu haben.

Das die Fertigung eines Herstellers ohne die Sortierung eine 
Normalverteilung den Nominalwert ergibt ist sowieso eine optimistischen 
Annahme.

Wie rechnet man das? Ich kenne zwei Methoden. Beide ignorieren die 
Realität wie Widerstände gefertigt und sortiert werden.

1. Intervallarithmetik
2. Monte-Carlos-Simulation.

> Also müssen nach dem Berechnen der Bauelementwerte diese auf E12
> gerundet werden.
> Wie kann man das elegant machen? gibts da einen Algorithmus für?

Die E-Reihen sind über einen Algorithmus berechenbar. Siehe Wikipedia
https://de.wikipedia.org/wiki/E-Reihe. Da es bei den alten Reihen eine 
Abweichung von der Rechenvorschrift gibt, und man heutzutage viel 
Speicherplatz hat, würde ich mir die Werte in Tabellen ablegen. In den 
Tabellen würde ich binär suchen, aber mit dem Trick, die Zweiteilung mit 
der Umkehrfunktion der Reihenfunktion zu optimieren (ist das dann noch 
eine binäre Suche? egal ...), also bei der Suche nicht mittig zu teilen.

> Ich hab bis jetzt die Holzhammermethode genommen: durch eine Tabelle
> aller E12 iterieren,

Suchen statt iterieren.

von Karl (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Kolja L. schrieb:
> Elegant ist, wenns funktioniert ;-)

So ist es. Solange die Vollraumsuche kurzer als eine Tasse Kaffee ist, 
lohnt sich aus betriebswirtschaftlicher Sicht keine weitere Optimierung. 
Das heißt nicht, dass man es aus akademischem Interesse nicht machen 
soll oder darf. Wir haben hier auch schon Sachen voll verrastert, die 
mehrere Tage Simulation nach sich zogen. Es hat halt nicht gestört.

von Peter M. (r2d3)


Bewertung
-1 lesenswert
nicht lesenswert
Hannes J. schrieb:
> Suchen statt iterieren.

Rechnen statt suchen. :)
Der Herstellungsprozess und die Verteilung der Widerstände infolgedessen 
hat nichts mit der Zuordnung auf die E12-Reihe zu tun, behaupte ich. 
Also nix Wahrscheinlichkeitsverteilung...
Solange die Widerstände innerhalb ihrer definierten Bandbreiten liegen, 
ist das irrelevant.

Eine binäre Suche ist nicht erforderlich.
Finden geht in konstanter Zeit.

Beispiel: 71.37412Ohm

Erstmal alles auf eine Dekade normieren: (Achtung, Zahlen verkürzt!)

log10(71.37412)=1,8535

(*1)  Abrunden ergibt 1 und Rest 0,8535.

Wir rechnen weiter mit den Rest:

0,8535*12+1=11,34
Abrunden ergibt 11.

Die 11 ist ein Schätzer für die Ordnungszahl (geht von 1 bis 12) aus der 
Dekade.

Jetzt ist es nur noch nötig, die prozentuale Abweichung des 
entsprechenden Wertes aus der Dekade (6,8) mit den Nachbarwerten 
(Ordnungszahl 10 und 12) zu vergleichen.

Wir potenzieren 10 mit dem Vorkommateil aus (*1) und multiplizieren mit 
dem Tabellenwert des Schätzers:

10^1 * E12[11] =  10 *6,8 = 68

Analog erfolgt die Rechnung mit den Nachbarn:

10^1 * E12[10] =  10 *5,6 = 56
10^1 * E12[12] =  10 *8,2 = 82

Jetzt einfach den Wert nehmen, der die Abweichung minimiert:
68

Die E12-Reihe kann man sich als Tabelle speichern, oder man baut sich 
eine kleine Generatorfolge (Formel stammt aus Excel):

(*2)
=ABRUNDEN((10^((C10-1)/12)+0,14)*10;0)/10-RUNDEN(REST(C10+7;12)/10;0)/10

Die Formel generiert für Werte von 1 bis 12 die praktischen E12-Werte 
der Basisdekade.

Die theoretischen Werte der E12-Werte erhält man über die Excel-Formel

(*3)      =ABRUNDEN(10^((C5-1)/12)*10;0)/10

Die Formel aus (*2) ist mit List, Tücke und Spucke aus (*3) entstanden.

Fazit
Großartiges Sparpotential bei Rechenzeit und Speicherplatz gibt es zwar 
nicht, und die Tabellensuche in E12[] geht natürlich schneller als die 
Anwendung der Formel.

Aber ich finde, es ist eine nette Idee, um die grauen Zellen ein 
bisschen auf Touren zu bringen.

von M. W. (elektrowagi78) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Die realen Werte kann man mit einem VBA-Script erledigen. Dann kann man 
auch Vorzugstypen einstellen.

von georg (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Falls noch Interesse besteht: beiliegendes Programm ausprobieren.

Installation ist nicht nötig, und Handbuch braucht man zur Bedienung 
auch nicht.

Georg

von Captain Albern (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Falls das schonmal geschrieben wurde: Ich habe nicht alle Antworten 
ausführlich gelesen.



Wenn X_brauche der Widerstandswert in Ohm ist, den macht braucht und E 
die Nummer der Reihe, dann kann man folgenden Index berechnen:

IDX = Runden( E * log10 (X_brauche) )

IDX ist dann der Index innerhalb der Reihe beginnend bei Index 0 = 1 
Ohm.

Der verfügbare Wert innerhalb der Reihe wäre dann X_kaufe=10^(IDX/E).

Das gilt aber deshalb nicht exakt, weil die Werte in den E-Reihen 
gerundet sind.


-----

Rechenbeispiel:

X_brauche = 0815 Ohm
E = 24 (E24-Reihe)

IDX = Runden(24*log10(815)) = 70

X_kaufe=10^(70/24)=825,4 Ohm

Tatsächlich ist der Index 70 der E24-Reihe mit 820 Ohm angegeben.

Zählung wie gesagt bei Index0=1Ohm anfangen.
Wenn man statt Ohm kOhm, µF oder sonstiges einsetzt, klappt das 
natürlich genauso.

von Walter T. (nicolas)


Bewertung
0 lesenswert
nicht lesenswert
Im großen und ganzen sind das neun Zeilen in Matlab. Geht bestimmt auch 
kürzer.
1
e = 12;
2
val = 0.00145;
3
4
% E-Reihe aufbauen
5
base = nthroot(10, e);
6
E = base.^(-1:(e+1));
7
Ebnd = 0.5*(E(1:end-1) + E(2:end));
8
9
% Wert herausfinden
10
dez = floor(log10(val));
11
val = val/(10^dez);
12
idx = (Ebnd(1:end-1)<val) & (Ebnd(2:end)>=val);
13
ott = 1:e+1;
14
idx = ott(idx)+1;
15
16
res = round( E(idx), 1 )*10^dez

von Peter M. (r2d3)


Bewertung
0 lesenswert
nicht lesenswert
Walter T. schrieb:
> Im großen und ganzen sind das neun Zeilen in Matlab. Geht bestimmt auch
> kürzer.

Habe gerade keine Matlab-Installation am laufen.
Du zählst Doch die theoretische Reihe auf und nicht die reale, oder?

von Walter T. (nicolas)


Bewertung
0 lesenswert
nicht lesenswert
Peter M. schrieb:
> Du zählst Doch die theoretische Reihe auf und nicht die reale, oder?

Jein. Da die Toleranzgrenzen ohnehin überlappen, ist die Frage ohnehin 
nicht besonders wichtig. Es wird der Wert zugeschlagen, der am 
dichtesten dran liegt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.