Soll heißen - ich möchte weder ein Genauigkeitsverlust noch eine Exponentialschreibweise. Auch die eigenwillige Formatierung soll beibehalten werden.
Ich habe mich bis jetzt wie folgt dem Problem gewidmet:
Code:
M = [3.1245785.47e+51.25e-3; 5532.154214785698542.5e-6];
dim = size(M);
string = repmat('%f, ',1,dim(2));
string = string(1:end-2);
string = ['[',string,'],'];
string = repmat(string,1,dim(1));
string = string(1:end-1);
spring = ['[',string,']'];
sprintf(string,M);
Vielen Dank für deine schnelle Antwort.
Sie löst aber leider noch nicht mein Problem, da ich mich nicht richtig ausgedrückt habe.
Du hast jetzt ja die Formatierungen hart ins sprintf reingeschrieben. Ich möchte aber später unterschiedliche Matrizen aus unterschiedlichen Files laden von den ich die Länge und Wertigkeit der einzelnen Elemente nicht kenne. Somit muss sich die Formatierung immer wieder auf die eingelesen Matrix adaptieren können.
das problem ist das ich keinen hintergrund in deinem formatierungsbeispiel sehe ^^. keine regel. darum kann ich das auch nicht automatisieren ^^ jeden string gleich zu formatieren oder die ersten 6 einträge oder was auch immer ist leicht. aber eine vorschrift für eine willkürliche formatierung ist hart ^^.
erkläre doch nochmal genau wie die einträge formatiert werden sollen. wie die werte vorliegen etz. was dir das command window anzeigt und was in der matrix gespeichert ist sind 2 paar schuhe ^^
_________________
Ich versuche es aufs Wesentlich zu reduzieren.
Mir geht es prinzipiell darum, einen ganzen Satz von verschiede Variablen (Skalar, Vektor, Matrix) einzulesen z.B. durch den Aufruf eines m-Skripts oder einer *.mat. Diese sich im Workspace befindlichen Variablen möchte ich gerne als String formatiert ausgeben, sei es in einer *.txt oder *.xml zur Weiterverarbeitung in anderen Programmen oder einfach über das Prompt. Hierbei sollte sich der Inhalt der Variable nicht verändern durch z.B. das Abschneiden von Zahlen oder Rundungen. Außerdem sollte die Zahl später nicht in Exponentialdarstellung vorliegen und keine nachfolgenden Nullen führen.
Ein Lösungsansatz habe ich mittlerweile finden können. Hier mal ein kleines Beispiel für zwei skalare Variablen, wobei ich hier die Kommastellen ermittle und dann mit .* die Auflösung festlege:
Gibt es noch eine andere Möglichkeit die Auflösung zu ermitteln und wie mache ich das Ganz jetzt bei Matrizen und Vektoren mit ganz unterschiedlichen Wertigkeiten der einzelnen Elemente?
Wie schon mal an anderer Stelle erwähnt, würde ich unbedingt das "clear all" weglassen. Wozu soll das nützlich sein? Da es auch alle Breakpoints löscht, behindert die das Debuggen.
Ich verstehe noch nicht den Zweck der von Dir gesuchten Funktion. Wenn Deine Lösung für einen Skalar funktioniert, kannst Du sie doch einfach in einer Schleife aufrufen, um eine Matrix zu bearbeiten, oder?
Zitat:
Hierbei sollte sich der Inhalt der Variable nicht verändern durch z.B. das Abschneiden von Zahlen oder Rundungen.
Dies ist eine unlösbare Aufgabe. Zahlen werden intern ja im Binär-Format gespeichert. Nun haben die meisten Dezimalzahlen keine exakte Darstellung im Binär-Format, wenn beide nur mit begrenzter Genauigkeit gespeichert werden. Umgekehrt gilt dies auch, also sind Fließkommazahlen im Binär-Format nicht generell exakt im Dezimal-Format darstellbar. Ein immer wieder auftauchendes Beispiel ist:
Das sieht so sehr nach 0 aus, dass Matlab-Nutzer (betrifft aber jede andere Programmiersprache, die den IEEE754-Standard benutzt) immer wieder verwundert sind, dass dies -2.775e-017 ergibt.
Die Konvertierung zwischen Binär- und Dezimal-Format lässt sich also nicht ohne rundung oder Abschneiden von Ziffern bewältigen. Du kannst zwar eine Menge Tricks versuchen, um den Einfluss zu verkleinern. Die V8-Bibliothek von Google benötigt für ein möglichst gutes FSCANF/FPRINTF auch mal eben 8 MB Source-Code. Aber auch damit lässt sch nicht verhindern, dass 0.3 intern eben 0.299999999999999 ist. Die Darstellung als 0.3 im Command-Window ist also bereits eine mehr oder weniger willkürliche Rundung.
Wenn Du wirklich Dezimal-Zahlen exakt in ein XML-File schreiben möchtest, musst Du die Binär-Zahlen zunächst in UINT8 aufteilen und dann als HEX- oder Base64 kodieren.
Code:
x = pi;
data = typecast(x, 'uint8');
string = sprintf('%.2x', data);
Besten Dank für eure Antworten und entschuldigt das ich mich jetzt erst melde.
Mittlerweile habe ich eine Funktion geschrieben die mir einen formatierten String für ein Skalar, ein Vektor oder einer Matrix ausgibt. Leider sind die numerischen Fehler, wie Jan sie beschrieben hat, weiterhin nicht wegzubekommen.
Diese numerischen Effekte kann man gar nicht "wegbekommen", denn sie sind Bestandteil der Methode Zahlen intern im Binärformat zu speichern und das Dezimal-Format für die Darstellung zu verwenden.
Das Problem löst sich sofort und ohne jegliche Tricks, wenn man entweder nur das Dezimal- oder nur das Binär-Format verwendet. Letzteres geschieht z.B. wenn man Zahlen per FWRITE im Biär-Format schreibt: Das ist schneller und vermeidet die zwei(!) Konvertierungen, die definitionsgemäß mit Rundungsfehlern behaftet sein müssen.
Statt "if isequal(Dimensions(1),1) && isequal(Dimensions(2),1)" ist dies viel sicherer: "if numel(Value) == 1".
Eine zuverlässige Methode müsste noch 3 und mehr Dimensionen abfangen.
Ich habe zu viele Versuche gesehen die Ausgabe der jahrelang massiv getesteten SPRINTF/SSCANF-Bibliotheken zu verbessern, die dabei als Bugs oder aus Unkenntnis der Details Fehler enthielten. Nichmal MathWorks hat diese Befehle selbst geschrieben, sondern dazu bestehende C-Routinen verwendet, weil sie einfach viele millionen Male getestet und über Jahrzehnte verbessert wurden. Deshalb rate ich von händischen "Verbesserungen" dringend ab und würde sie unter keinen Umständen für produktive Arbeit verwenden. Wenn man mal ein paar Milliarden Zahlen in Files geschrieben hat um sie für eine Wissenschaftliche Studie auszuwerten, wäre ein noch so kleiner Bug ein Desaster.
Gruß, Jan
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.