Hallo, da ich für die Verarbeitung von Daten auf einem Mikrocontroller
Variablen vom Typ float, integer und char verwende, benötige ich
Funktionen mit denen ich die Typen umwandeln kann.
Z.B. flott umwandeln in char* oder char* in float
Mit den sprintf sowie sscanf Funktionen hab ich dies schon versucht.
char* in float kann ich umwandeln, nur nicht umgekehrt. Gibt es eine
Funktion mit der ich dies tun kann?
Was für einen Sinn macht es, einen Pointer auf eine 8-Bit-Variable in
eine float-Variable zu wandeln? Und umgekehrt?
Was willst du denn genau machen?
Normal brauchst du das nur zu Casten, aber bei Float -> Char wirds schon
sinnbefreit, weil float ja meinetwegen 12.45678 als Wert hat, char aber
nur einen Wertebereich zwischen -128 und +127 in ganzen Zahlen.
Ich möchte einen float Wert Beispiel 12.3456 in ein char Array ablegen.
4 Bytes (char) entsprechen ja einem float Wert.
Wie kann ich es hinbekommen, dass ich einen float Wert in 4 Bytes
ablegen kann und umgekehrt?
Es ist unklar, was du nun willst. Einen float in einen char* umwandeln
wohl nicht, denn das ist ziemlich sinnfrei. Wohin sollte denn das
Bitpattern eines float, wenn man es als Zeiger interpretiert, zeigen?
Du schreibst was von sprintf und sscanf, was nahelegt, daß du eine
Stringrepräsentation des Wertes haben willst. Dann aber schreibst du:
"4 Bytes (char) entsprechen ja einem float Wert. Wie kann ich es
hinbekommen, dass ich einen float Wert in 4 Bytes ablegen kann und
umgekehrt?", was eher darauf hinweist, daß du den float-Wert als Array
aus Bytes interpretieren willst, z.B. um es als Binärdaten irgendwo
hinzusenden. In dem Fall wäre sprintf/sscanf die falsche Wahl.
Also, was willst du?
Ja ich möchte einen float-Wert als Array aus Bytes interpretieren, z.B.
um es als Binärdaten irgendwo hinzusenden.
Das meinte ich auch. Hab ich sehr schlecht ausgedrückt. Ich bitte um
Entschuldigung.
>Ja ich möchte einen float-Wert als Array aus Bytes interpretieren, z.B.>um es als Binärdaten irgendwo hinzusenden.
Ich glaube dafür brauchst du keine Funktion, da reicht wie schon erwähnt
ein typecast oder man sogar darauf noch verzichten.
...
float fv=3.1415f;
float fc;
char *fewbytes=(char *) &fv;
...
#include <mem.h>
main() {
float fv=3.1415f;
float destination;
memcpy(&destination,&fc,sizeof(fv));
}
char array[10];
void FloatToString(float fvalue,char* buf)
{
int i;
unsigned char charPtr;
for (i=0;i<4;i++)
{
charPtr = *((char*)fvalue+i);
buf[3+3-i] =charPtr;
}
}
void main (void)
{
....
FloatToString(12.3456,array);
....
}
Dies müsste doch so gehen oder? Im array sind dann 4 Bytes enthalten.
Ich hab die Funktion nicht getestet.
Gehen wir das mal durch:
> void FloatToString(float fvalue,char* buf)
Wieso heißt die Funktion "FloatToString"? Sie soll doch gar keinen
String erzeugen.
> charPtr = *((char*)fvalue+i);
Das ist ziemlicher Unsinn, und zwar in jedem Detail. Zuerst werden die
Bits, aus denen fvalue zusammengesetzt ist, als Zeiger interpretiert.
Dan wird dieser Zeiger um i erhöht. Danach wird das Byte gelesen, auf
das dieser zeigt. Das was dort steht, wird dann wieder in einen Zeiger
umgewandelt und charPtr zugewiesen.
> buf[3+3-i] =charPtr;
Hier auch wieder das Byte, das an dem angegebenen Index steht, mit dem
Zeigerwert (und nicht dem Wert der Speicherstelle, auf die er zeigt)
gefüllt. Übrigens: Wie bist du beim Index auf 3+3-i gekommen? Damit
schreibst du hinter das Ende des Arrays.
> void main (void)
main muß int zurückliefern.
void FloatToCharArray(float fvalue)
{
unsigned char buf[5];
int i;
unsigned char charPtr;
for (i=0;i<4;i++)
{
charPtr = *((unsigned char*)fvalue+i);
buf[3-i] =charPtr;
}
}
void main (void)
{
....
FloatToCharArray(12.3456);
....
}
So Funktioniert die Funktion. In buf[0] bis buf[3] stehe dann die Werte
drin.
Wie kann ich den buffer buf zurückgeben, so dass ich dann die Werte
außerhalb verwenden kann?
Wie wandelt man nun die 4 Bytes wirder um in einen Float Wert?
> So Funktioniert die Funktion.
Mit Sicherheit nicht. Du interpretierst immer noch einen Float als
Adresse. Hast du die Diskussion gelesen, auf die ich verlinkt habe?
> Wie wandelt man nun die 4 Bytes wirder um in einen Float Wert?
Auch das hättest du der verlinkten Diskussion entnehmen können.
void FloatToCharArray(float fvalue)
{
unsigned char buf[5];
int i;
unsigned char charPtr;
for (i=0;i<4;i++)
{
charPtr = *((unsigned char*)&fvalue+i);
buf[3-i] =charPtr;
}
}
void main (void)
{
....
FloatToCharArray(12.3456);
....
}
Ich Adressoperator & vor der Variable fvalue vergessen.
>>Auch das hättest du der verlinkten Diskussion entnehmen können.
Also diese Diskussion hat mir nicht sonderlich viel geholfen
> Also diese Diskussion hat mir nicht sonderlich viel geholfen
Dann zitiere ich mal den wesentlichen Teil:
1
floattmpBuffer;
2
char*buffer=(char*)&tmpBuffer;
Das wäre ohne Kopieren. Wenn du die Bytes kopieren willst:
1
memcpy(buf,f,sizeof(f);
Hier ist f die float-Variable und buf ein 4 Bytes großes char-Array.
die beiden Varianten drehen allerdings die Reihenfolge der Bytes nicht
um. Wenn du das willst, ist deine Variante in Ordnung.
Mir ist gerade erst aufgefallen, daß ich oben zum Teil was Falsches
geschrieben hab, weil ich angenommen hatte, charPtr sei ein Zeiger auf
char. Der Name ist etwas unglücklich gewählt.
Dein Code sieht jetzt ok aus. Warum ist buf jetzt 5 Bytes groß?
Zur Ausgabe des Puffers: Den kannst du aus der Funktion nicht rausgeben,
weil er nur solange existiert, wie die Funktion ausgeführt wird.
Stattdessen kann aber der Aufrufer den Puffer anlegen und einen Zeiger
darauf an die Funktion übergeben. Also so wie du es am Anfang mal
gemacht hast.
Zum Testen, hab verwende ich die Software Microsoft Visual Studio 6.0
C++.
Folgende Fehlermeldungen erhalte ich beim comilieren:
>warning C4305: '=' : Verkuerzung von 'const double' in 'float'>error C2664: 'memcpy' : Konvertierung des Parameters 2 von 'float' in 'const >void *' nicht moeglich
> So meinst du das?
Ja, wobei für dein Array 4 gereicht hätten, also
1
unsignedchararray[4];
oder gar
1
unsignedchararray[sizeof(float)];
> Mit dieser Zeile kann ich dann den float Wert in ein char Array (4> Bytes) kopieren?
Ich bin wohl noch nicht ganz wach. Ich hab übersehen, daß die Zeile so
nicht richtig ist. Aber im Prinzp ja. Wie gesagt werden dabei allerdings
die Bytes nicht umgedreht, so wie du es in deinem Code machst.
> Welche Header Datei muss ich hierfür noch zusätzlich includen?
<string.h>
In deiner Funktion müßte die Zeile so aussehen:
>warning C4305: '=' : Verkuerzung von 'const double' in 'float'
Das kommt, weil 12.3456 vom Typ const double ist. Die Warnung kannst du
wegbekommen, indem du daraus 12.3456F machst. Dann ist der Wert
derselbe, aber der Typ ist const float.
>error C2664: 'memcpy' : Konvertierung des Parameters 2 von 'float'> in 'const void *' nicht moeglich
Das kommt, weil beim zweiten memcpy-Parameter ein & fehlt. Mea culpa.
@StinkyWinky:
Jetzt mach den armen Cnewbie nicht noch konfuser...
@Cnewbie:
Dir würde ich dringend empfehlen, ein C-Tutorial für Anfänger Schritt
für Schritt durchzuarbeiten und die Beispiele auch wirklich zu
programmieren. Anders wird das nämlich nichts.
> Dies müsste doch so gehen oder? ... Ich hab die Funktion nicht getestet.
Solche Aussagen getraue ich mir selbst nach 20 Jahren C-Erfahrung nicht.
Du bist echt so ein Großkotz Uhu Uhuhu!
Dieser Code funktioniert prima.
unsigned char array[10];
void FloatToCharArray(float fvalue,char* buf)
{
int i;
unsigned char charPtr;
for (i=0;i<4;i++)
{
charPtr = *((unsigned char*)&fvalue+i);
buf[i] =charPtr;
}
}
Wenn ich nun 4 Bytes in ein float Wert umwandeln möchte und zwar so
ähnlich wie die obige Funktion, wie müsste man diese realisieren?
CNewbie es gibt ein gutes Buch.
C/C++ für Dummies! Das würde ich jedem empfehlen, der an solch einer
Aufgabe so verzweifelt ;) Ist nicht bös gemeint damit habe ich auch
angefangen vor ca. 10 Jahren! ;)
Die einfachste Lösung ist echt wie Rolf Magnus schreibt:
float tmpBuffer;
char* buffer = (char*)&tmpBuffer;
Oder
float f = 5.5f;
char buf[4];
memcpy(buf,&f,sizeof(f);
Ich verstehe grad nicht weshalb das jetzt noch weiter diskutiert werden
muss. Man muss nicht immer das Rad neu erfinden.
P.S. die Rückumwandlung von char[4] in float sieht dann so aus:
memcpy (&f, buf, sizeof(buf));
Cnewbie wrote:
> Du bist echt so ein Großkotz Uhu Uhuhu!
Das scheint dein eigentliches Problem zu sein: Kein Sitzfleisch, dir
Dinge anzueignen, die etwas komplexer sind, als ein Laib Brot.
Es ist noch kein Software-Ingenieur vom Himmel gefallen. Von Geburt aus
nicht programmieren zu können ist keine Schande.
Peinlich wirds allerdings, wenn man meint, irgendwo mittendrin
einsteigen zu können, ohne die Grundbegriffe zu kennen.
Also: Lerne erstmal was, dann helfen wir dir hier gerne weiter. Auf dem
Niveau von Putzfrauenwissen über Programmierung macht das keinen Spaß
und bringt dir letztlich auch nicht viel.
Einen recht ordentlichen Eindruck macht übrigens das C-Tutorial bei
http://www.roboternetz.de/wissen/index.php/C-Tutorial