Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » bytearray to double

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
14.11.2017, 13:53 Uhr
user21031993



Hallo zusammen,

ich bin neu hier und kämpfe seit einiger Zeit mit folgendem Problem:

Und zwar versuche ich mich daran eine bestehende mex-Funktion (mpack.cc) auf VisualStudios2015 etwas umzuschreiben bzw. zu verbessern.
Mein konkretes Problem ist, dass ich in dieser mpack.cc ein bytearray (usigned char) habe und dieses gerne in ein double-Array umformen möchte, da immer 8 Bytes aus diesem Array eine Double-Zahl codieren (Bsp.: 64 0 0 0 0 0 0 0 = 2). Mithilfe der Matlab-Funktion 'mxCreateNumericMatrix()' kann ich die Double-Werte dann in die gewünschte m x n - Matrix schreiben und an Matlab "übergeben".
Auf meiner bisherigen Suche nach der Lösung dieses Problems bin ich nur auf die .Net Framework Klasse 'BitConverter' gestoßen. Jedoch kann ich diese nicht anwenden, da ich dafür mit clr compilieren müsste und wenn ich das korrekt verstanden habe, wird meine funktion ja von matlab kompiliert. Jedenfalls bekomme ich für die Zeile: " using namespace System; " den Fehler: " 'System': a namespace with this name does not exist"

Wenn jemand eine Idee hat, wie ich die BitConverter-Klasse (falls möglich) zum laufen kriege oder die Umformung BytearrayToDouble anderweitig lösen könnte, wäre ich sehr dankbar!

Ich hoffe ihr könnt mit meiner Beschreibung etwas anfangen...

Mit den besten Grüßen,

Florian M

Dieser Post wurde am 14.11.2017 um 14:04 Uhr von user21031993 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
14.11.2017, 15:53 Uhr
ao

(Operator)


Ob und wie man C#-Code in mex-Files einbinden kann, weiß ich nicht.

In C kann man sowas mit unions machen, in C++ gibts dafür std::bitset (oder ebenfalls union).

Unions (auch Varianten genannt) sind von der Syntax her genauso wie structs. Der Unterschied ist, dass in der struct die Member hintereinander im Speicher liegen und in der Union alle auf derselben Stelle. Mit einer Union kann man also ein Stück Speicher als unsigned-char-Array befüllen und anschließend als double auslesen.

Das ist natürlich hochgradig unportabel wie alles, was direkt mit der Zahlendarstellung der CPU und des Compilers spielt, aber solange man es nicht in zu vielen verschiedenen Umgebungen verwenden will, ist es ziemlich straight forward.

Hier ist ein einfaches Beispiel, lauffähig auf Ubuntu 16.04 (x86_64, gcc 5.4). Wie man daraus eine mex-Funktion macht, weißt du wahrscheinlich besser als ich.

C++:
#include <stdio.h>
#include <string.h>

/* define union type */
union Converter
{
    /* a double and an array of unsigned char,
     * overlapping in memory */

    double d;
    unsigned char bytes[8];
};

int main (void)
{
    /* declare variable of union type */
    union Converter c;
    
    /* create input data */
    unsigned char input [] = { 0, 0, 0, 0, 0, 0, 0, 64 };

    /* fill input data into char-array portion of union variable */
    memcpy (c.bytes, input, 8);
    
    /* read and print double portion of union variable */
    printf ("%lf\n", c.d); /* result is 2.000000 */
    
    return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
14.11.2017, 17:34 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



Zitat:

... mpack.cc ...



klingt eher nach c++ und nicht c#

auch die Fehlermeldung


Zitat:

'System': a namespace with this name does not exist



klingt mehr nach C++

Kann es sein das du die Sprachen verwechselt hast?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
14.11.2017, 18:16 Uhr
ao

(Operator)


Es ist vermutlich "C++ für .NET", diese unsägliche Monstersprache, vor der man nur warnen kann. Wenn ich ein Mex-Compiler wäre, würde ich mich auch weigern, das zu übersetzen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
15.11.2017, 00:57 Uhr
user21031993



Vielen Dank für die schnellen Antworten,

mit 'union' funktioniert es soweit erstmal super. Nur habe ich jetzt noch ein Problem mit der endianness... In meinem Bytearray ist die Zahl zwei nämlich so -> {64, 0, 0, 0, 0, 0, 0, 0} und nicht wie im Beispiel von ao andersherum codiert.
Und da in meinem Bytearray nicht nur eine double codiert ist, bin ich gerade auf der Suche nach einer Lösung zum switchen der endianness mit möglichst geringem Rechenaufwand...

Falls dazu vielleicht jemand einen passenden Vorschlag parat hat, würde er mir damit erneut sehr weiterhelfen, da ich mich mit c++ nicht besonders gut auskenne und ehrlich gesagt auch nicht mal weiß, wie ich herausfinde ob eine Lösung unnötig langsam ist oder nicht. Bisher bin ich z.B. auf '_byteswap' gestoßen.

https://stackoverflow.com/questions/105252/how-do-i-convert-between-big-endian-and-little-endian-values-in-c

Jedoch müsste ich dafür ja durch eine for-schleife jeden double-Wert einzeln "switchen" oder nicht?!?

Und ja ich bin versehentlich falsch gelandet, ist natürlich c++ und nicht c# *sry*
Ihr dürft den Thread natürlich gerne verschieben oder muss ich das selbst tun? Wenn ja wie und wohin genau? ...weil es gibt ja mehrere übergeordnete Themen zu c++

Vielen Dank und Gruß,

Flo

Dieser Post wurde am 15.11.2017 um 01:03 Uhr von user21031993 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
15.11.2017, 11:22 Uhr
ao

(Operator)



Zitat von user21031993:
In meinem Bytearray ist die Zahl zwei nämlich so -> {64, 0, 0, 0, 0, 0, 0, 0} und nicht wie im Beispiel von ao andersherum codiert.

Wo stammen diese Byte-Arrays denn her, und warum sind das überhaupt Byte-Arrays, wenn in Wirklichkeit doubles dahinterstecken?

Ich frage hier nach der Wurzel des Übels. Vielleicht kann man das auch direkt an der richtigen Stelle anpacken?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
15.11.2017, 11:24 Uhr
ao

(Operator)


Ich verschiebe das nach ANSI C/C++. Die Umwandlung von Zahlenformaten ist ein allgemeines Problem, und dass es hier um Matlab geht, hat nichts damit zu tun.
Dieser Post wurde am 15.11.2017 um 11:41 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
15.11.2017, 11:36 Uhr
ao

(Operator)



Zitat:
Bisher bin ich z.B. auf '_byteswap' gestoßen

Wenn du byteswap naiv verwendest

C++:
double unswapped = 3.1415927;
double swapped = _byteswap_uint64 (unswapped);

dann wird der Compiler den double zuerst zu uint64 konvertieren (aus Pi wird 3), dass dann swappen (es entsteht eine sehr große Zahl) und zu double zurückkonvertieren. Dabei kommt nicht das raus, was du willst.

Wenn man byteswap verwenden will, muss man vorher ein memcpy machen von dem double in ein uint64-Hilfsobjekt und hinterher dasselbe zurück.Wahrscheinlich ist es effizienter, den swap selber zu kodieren (z.B. mit der union von oben, und dann die Bytes im Array in-place tauschen).

Dieser Post wurde am 15.11.2017 um 11:38 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
16.11.2017, 13:14 Uhr
user21031993



Vorerst danke nochmal für deine Mühen,

wie ich bereits erwähnt habe ist es meine Aufgabe eine bestehende Mex-Funktion zu verbessern. Prinzipiell kann man mithilfe dieser Funktion (Ausgangsfunktion) Arrays, Strukturen oder Einzelwerte in verschiedensten Datentypen von Matlab aus verpacken oder in Matlab entpacken (wenn man beispielsweise die Daten von irgendwo anders ausliest.
Die Daten werden nach folgendem Schema gepackt:

https://github.com/msgpack/msgpack/blob/master/spec.md

Es gibt an der bisherigen (fertigen) Funktion jedoch zwei Probleme, die ich beheben soll.
1. : In einem Array (was ja im Normalfall ohnehin aus gleichen Datentypen besteht) wird für jeden Wert jeweils der entsprechende Datentyp mitverpackt bzw. beim entpacken erwartet die Funktion vor jedem Wert ein Byte, das den Datentyp codiert. Und angenommen das Array hat eine Million Werte, dann sind 999999-Bytes überflüssig.

2. : Die Dimensionen werden nicht berücksichtigt. Wenn z.B. eine 5 x 10 Double-Matrix aus Matlab verpackt wird, steckt in dem verpacktem Bytearray anschließend keinerlei Information über die Dimension, sprich es ist genauso wie eine 1 x 50 Double-Matrix.

Lösen will ich beide Probleme mit der ext-Familie (siehe Link), da ich hier ein Byte für den Type (in meinem Fall eben den Datentyp) habe und in dem Format in einem, zwei bzw. vier Bytes die Anzahl der Datenbytes festgelegt wird. Die Dimensionen (maximal 2) verstecke ich einfach am Anfang der Datenbytes.

Das verpacken funktioniert bereits auch schon so wie ich es will und beim entpacken erhalte ich auch die Dimensionen zurück und eben einen Pointer auf den ersten Wert des Datenarrays in dem dann alle Werte hintereinander (ohne Datentyp-Codierung) stehen. Nur eben in der Endianness wie bereits beschrieben.
Prinzipiell ist die Endianness auch gar nicht falsch, da die Mex-Funktion bisher auch so rum gepackt hat und das auch korrekt entpacken konnte, jedoch konnte ich bisher noch nicht wirklich erkennen an welcher Stelle im Code bzw. wie beim entpacken in der Funktion wieder die double-Werte (oder auch Singles, logicals, ints...) gebildet werden, weil ich wie gesagt ein ziemlicher Anfänger in c#/c++ bin und in die eigentliche mex-funktion gefühlt 100 header-funktionen eingebunden sind. =(

Falls du oder sonst jemand sich das ganze mal genauer anschauen wollen würde, könnte ich auch gerne den git-clone link für die ganzen Dateien geben, jedoch würde das wohl auch voraussetzen, dass man Matlab hat...

So ich hoffe ich habe die Umstände für mein Problem jetzt einigermaßen gut beschrieben und freue mich auf jede weitere Hilfe.

Gruß,

Flo

Dieser Post wurde am 16.11.2017 um 13:15 Uhr von user21031993 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
16.11.2017, 13:24 Uhr
user21031993



Zu allem Überfluss ist mir gestern auch noch die Festplatte abgeschmiert...
Somit bin ich jetzt erstmal damit beschäftigt das ganze überhaupt wieder zum laufen zu bringen auf meinem anderen Rechner.
Habe dabei nämlich auch schon wieder das nächste Problem, da ich beim debuggen nur noch an Breakpoints komme, die sich in der Hauptfunktion befinden, weil für diverse "Nebenfunktionen" und Headerfunktionen scheinbar die Symbole nicht geladen wurden.
Und leider konnte ich diesen Umstand zusammen mit Google gestern nicht lösen...

Jemand ne Idee an was das liegen könnte?

Gruß Flo
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: