WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Rundungsfehler bei str2num(dec2bin(X))

 

Cappaja
Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 11.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2011, 14:07     Titel: Rundungsfehler bei str2num(dec2bin(X))
  Antworten mit Zitat      
Hallo,

ich habe ein Rundungsproblem bezüglich der Funktion dec2bin bzw str2num.
R ist hierbei ein Vektor von Integer-Werten die binär maximal 24Bit groß sein können.
Wenn ich einen vorliegenden Wert (10488788) anstelle von R übergebe erhalte ich für K letztlich 10488704. Der Fehler entsteht bereits nach der ersten Zeile. Für str2double reicht der Wertebereich (52Bit) für num2str() wiederum nicht aus, das hatte ich auch schon versucht da es Matlab empfohlen hatte.
Kennt jemand eine Lösung für das Problem?

Code:

S(:,i) = str2num(dec2bin(R));
K(:,1) = bin2dec(num2str(S(:,2)));
 


Mit freundlichen Grüßen

Cappaja
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 25.05.2011, 14:37     Titel: Re: Rundungsfehler bei str2num(dec2bin(X))
  Antworten mit Zitat      
Hallo Cappaja,

Für R = 10488788 erzeugt DEC2BIN einen String der Länge 24. STR2NUM wandelt dies in einen DOUBLE um, der 52 Bits für die Mantisse bietet. Das reicht für 16 gültige Ziffern. Das umgewandelte R hat aber 24 Ziffern, so dass STR2NUM rundet.

"Lösen" läßt sich das nicht. Die von Dir vorgenommene Zahlenumwandlung ist einfach so nicht durchführbar. Wozu soll die DEC->BIN->DEC Konversion denn dienen? Wie wäre es, wenn Du die Bits als UINT8 Vektor speicherst?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Cappaja
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 11.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2011, 14:58     Titel:
  Antworten mit Zitat      
Hallo Jan,

die Daten vom Sender werden als komprimierter Binärstrom übertragen. Beim Empfänger sollen diese wieder 1:1 dekomprimiert werden. Zwischen diesen beiden Funktionen fehlt natürlich einiges an Code aber das tut meinem Problem nichts zur Sache.
Die 24-Bit in 8-Bit Vektoren abzulegen ist ein wenig umständlich zumal Echtzeitfähigkeit später eine wichtige Rolle spielt...
Gibt es wirklich keine andere Möglichkeit?

Grüße Cappaja
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 25.05.2011, 15:59     Titel:
  Antworten mit Zitat      
Hallo Cappaja,

Zitat:
Die 24-Bit in 8-Bit Vektoren abzulegen ist ein wenig umständlich zumal Echtzeitfähigkeit später eine wichtige Rolle spielt..

Zur Zeit legst Du sie per DEC2BIN in 16-bit CHARs ab. Das sollte also langsamer sein. Nebenbei sind DEC2BIn und STR2NUM sehr langsame Funktionen und die Konversionerscheint mir nachwievor befremdlich. Kannst Du nochmal genau posten, welche Werte du in welcher Form kodieren möchtest?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Cappaja
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 11.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2011, 16:56     Titel:
  Antworten mit Zitat      
Hallo Jan,

ein besonders kleiner und nicht gerade optimaler Testdatensatz aber zum Verständnis sollte es ausreichend sein.

1.) Originaldaten
[ 209775.76; 172817.48; 31703.36 ]

2.) Differential Coding:
[209775.76; 36958.28; 141114.12 ]

3.) Nach Teilen durch Skalierungsfaktor (0.02):
[ 10488788; 1847914; 7055706 ]

4.) Binärdatenstrom erzeugen
[ 101000000000101111010100; 111000011001001101010; 11010111010100101011010 ]

5.) Daten übertragen (HTTP basiertes Übertragungsprotokoll unidirektional)

6.) Binärdatenstrom dekodieren sodass Originaldaten herauskommen

Wenn es eine andere Möglichkeit gibt soll es mir recht sein...
Ziel ist es den Grad verschiedener Kompressionsverfahren im Mittel prozentual zu erfassen. So kann ich 24-Bit teilweise bis auf 1 Bit abbilden und reproduzieren, in diesem schlechteren Beispiel auf 21 bzw 23-Bit

Grüße Cappaja
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 27.05.2011, 09:53     Titel:
  Antworten mit Zitat      
Hallo Cappaja,

Die Testdaten sind sehr hilfreich!

Zitat:
[ 209775.76; 172817.48; 31703.36 ]

Ich nehme an, das ist ein DOUBLE Vektor.

Zitat:

2.) Differential Coding:
[209775.76; 36958.28; 141114.12 ]

3.) Nach Teilen durch Skalierungsfaktor (0.02):
[ 10488788; 1847914; 7055706 ]

4.) Binärdatenstrom erzeugen
[ 101000000000101111010100; 111000011001001101010; 11010111010100101011010 ]

"Binärdatenstrom" bedeutet ja nun physikalisch einen Strom aus binären Daten. Dann hast Du aber nach Punkt 4 dies:
[1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 1 1 0 1 0 1 0 1 1 0 1 0 1 1 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0]
Wie man daraus wieder [10488788; 1847914; 7055706] erzeugen kann, bleibt mir verborgen. Du müssest also zumindest noch die Lauflänge der einzelnen Zahlen einfügen. Wenn Du weißt, dass alle Zahlen weniger als 32 bit haben, reichen 5 Bit dafür aus - pro Zahl! Wegen des Differential-Coding haben die meisten Zahlen aber eine geringe Anzahl von Bits, so dass diese 5 Bit Lauflänge wohl einen deutlichen Overhead liefern werden.

Wenn Du die [10488788; 1847914; 7055706] als UINT32 castest (siehe CAST oder einfach "uint32(...)"), hast Du eine feste Breite für alle Zahlen, also führende Nullen als overhead.
Wenn die Zahlen aber alle kleiner als 2^24 sind, kannst Du sie auch als 24-Bit-Zahlen schreiben: siehe FWRITE mit dem 'ubitN' Format. Dies wäre auch sehr hilfreich, wenn Du mit einzelnen Bits jonglieren möchtest. Zunächst würde ich (wie schon erwähnt) einen UINT8-Vector im Speicher erzeugen, der die einzelnen Bits enthält. Beim Senden über das Netz werden dann aber per 'bitN'-Format die führenden 7 Bits weggelassen, so dass Du einen reinen möglichst kompakten Binärstrom hast. Das Umwandeln in CHARs wäre dabei hinderlich - DEC2BIN sollte eigentlich DEC2_16BIT_CHAR_STRING heißen, was schnell klar machen würde, dass dabei 15 Bit pro Ziffer "vergeudet" werden.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Cappaja
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 11.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.06.2011, 14:27     Titel:
  Antworten mit Zitat      
Hallo Jan,

erstmal vielen Dank für die durchaus umfangreiche und hilfreiche Antwort. Ich übertrage den Binärdatenstrom jetzt mittels FWRITE mit dem Format ubitN. Für einfache Datensätze funktioniert alles soweit wunderbar, nur für dreidimensionale Matrizen hab ich noch Probleme. Es erscheint die Fehlermeldung "Invalid size". Das hat mit dem Übergabeparameter SIZE der Funktion FREAD zu tun.

Ein Datensatz (Messdaten + Vorzeichenbit) zu einem diskreten Zeitstempel (hier 26) sieht folgendermaßen aus:
R(:,:,26) =

8563301 0
3499882 0
4223357 1
9286776 0
7528168 1
3633797 1
0 0
8886520 0
0 0

Funktioniert, allerdings erhalte ich nur R(:,:,1)
Code:

n = size(R);
K = fread(fid, [n(1) n(2)],'ubit24=>uint32');
 


Funktioniert nicht, Fehlermeldung "Invalid size"
Code:

n = size(R);
K = fread(fid, [n(1) n(2) n(3)],'ubit24=>uint32');
 


Ich möchte quasi aus dem Datenstrom
3
4
5
1
0
0
6
4
9
0
1
0

das hier machen:
K(:,:,1) = [3 1; 4 0; 5 0;] K(:,:,2) = [6 0; 4 1; 9 0] usw...
Die Schrittweiten sind dabei konstant.

Weiß jemand wie ich das mittels dem Parameter SIZE der Funktion FREAD elegant lösen kann?

Grüße Cappaja
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 03.06.2011, 22:33     Titel:
  Antworten mit Zitat      
Hallo Cappaja,

Code:
n = size(R);
K = reshape(fread(fid, prod(n), 'ubit24=>uint32'), n);
 

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Cappaja
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 18
Anmeldedatum: 11.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.06.2011, 14:49     Titel:
  Antworten mit Zitat      
Hallo Jan,

hat alles prima funktioniert! Ich danke Dir!

Grüße Cappaja
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.