C aus double eine int/char machen, union richtig benutzen?

ReVo

Lieutenant
Registriert
Jan. 2006
Beiträge
567
Hallo,

zuerst dachte ich, das ist relativ leicht, aber jetzt sehe ich, dass ich das doch nicht richtig kann. Also mit variant(union) kann man zb. aus einem double int machen. Aber weiß jetzt nicht genau wie bzw. wie ich das hier bei meine aufgabe anwenden soll.

Also ich muss aus einem double wert einen string machen. Genauer gesagt "schreiben sie eine funktion die das bitmuster eines eingegeben double wertes als string zurückgibt"

Nun, die funktion wie ich bei einem integer alles in bitdarstellung habe kenne ich:

Code:
  int i = 0;
  int j = 0;
  int k = 1;
  int = zahl;

  printf("Bitte eine Zahl eingeben: ");
  scanf("%d", &zahl);

  while(d != 0)
  {
    i = zahl & 1;
    zahl>>=1;
    j = j + (i * k);
    k = k * 10;
  }
	
  printf("\Als bit: %d\n", j);

aber jetzt müsste ich denke ich aus alles eine double machen und das als char zurückgeben. Ersetze ich die int variablen durch eine double, geht das alles nicht mehr. Darum muss das jetzt mit union gehen. Ich verstehe sogar warum, weil union alle variablen auf dem gleichen speicher legen kann. Nur weiß ich jetzt nicht wie ich das hinschreibe :/

Irgendwelche tips?

Gruss
 
hi,

hier mal was auf die Schnelle:
(hoffe ich hab dich richtig verstanden)
Code:
//buffer: mindestens 65byte(char)
void WhatEverName(double num,char* buffer)
{

	unsigned long long BitMsk=0x8000000000000000;
	unsigned long long* pNum=(unsigned long long*)#	
	for(int i=0;i<64;i++)
	{
		buffer[i] = (pNum[0]&BitMsk)?'1':'0';
		BitMsk = BitMsk>>1;		
	}
	buffer[64]=0;
}
 
Zuletzt bearbeitet:
ReVo schrieb:
Also mit variant(union) kann man zb. aus einem double int machen.
[...]
Darum muss das jetzt mit union gehen. Ich verstehe sogar warum, weil union alle variablen auf dem gleichen speicher legen kann.

Hallo,

genau das kann man mit Union machen, aber es ist eine "Vergewaltigung" von Unions. Du umgehst damit das Typsystem der Sprache und jegliche Sicherheitsmaßnahmen. Du gibst quasi der Sprache/dem Compiler keine Chance es richtig zu machen, sondern interpretierst die binäre Repräsentation selbst (etwas, was immer die Maschine machen sollte (die weiß immernoch ma besten wie es geht), es sei denn, es ist zwingend notwendig)

Die Sprache definiert übrigens, dass du aus einer Union nur genau das Element lesen darfst, das du auch als letztes reingeschrieben hast. Unions zu benutzen ist definitiv der falsche Weg. Zumal die niemand garantiert, dass int und double die selbst Größe haben.

Soviel dazu. Du brauchst (und darfst) aus dem double keinen int zu machen, wenn du die Aufgabe lösen willst. Da das eine Hausaufgabe zu sein scheint, will ich dir mal nicht die komplette Lösung hinschreiben.

Aber als Ansatz:
mit sizeof( double) bekommst du die Größe des doubles im Speicher zurück. Mit unsigned char* c = (unsigned char*)(&doubleVariable) kommst du dann an die binäre Darstellung und kannst dann mit dem Pointer über den Double wandern und die gesetzten Bits auslesen.
 
Zuletzt bearbeitet: (Bugfixing... :))
Hi,

danke für die tips ^^, leider muss man die aufgabe mit union machen :freak: , so ist es verlangt. Aber dass das so "böse" ist war mir selber noch nicht ganz klar :D

Gruß
 
Du "musst" die mit Union machen? :freak: Klingt irgendwie nach Berufsschullehrern...

Den "Union-Cast" kann man so basteln:

Code:
typedef union {
  int i;
  double d;
} Evil;

int unionCast( double d)
{
  Evil x;
  x.d = 1.23456789;
  return x.i;
}

Interessant wäre mal, ob bei dir sizeof(double) und sizeof(int) übereinstimmen. Sonst siehst du nur einen Teil der Daten, die den double ausmachen.

Es macht übrigens - sofern überhaupt - nur dann Sinn, wenn man mit einem unsigned int arbeitet (da liegt übrigens auch ein Fehler in meinem vorherigen Post - du musst unsigned char verwenden).
Dein Algorithmus, den du im ersten Post eingefügt hast, ermittelt übrigens nur die binäre Darstellung des int's. Diese muss nichts mit der binären Repräsentation im Speicher zu tun haben (Stichwörter hierzu sind Little/Big-Endianess und Darstellung von negativen Zahlen).

Von daher müsstest du auch mal sagen, welche du eigentlich brauchst. :)
 
Zuletzt bearbeitet:
7H3 N4C3R schrieb:
Den "Union-Cast" kann man so basteln:
Unabhängig von deinem Beispiel, solche Vorgehensweisen sind nicht zu empfehlen. Hier hat man übrigens das Problem, dass int und double noch lange nicht gleich viele Bits haben müssen. Auf gängigen 32 und 64 Bit Systemen haben sie das auch nicht. Dann werden entweder Informationen abgeschnitten oder nicht initialisierte Daten verwendet.
Generell ist festzuhalten, Unions sind nicht für solche "dreckigen" Cast Geschichten gedacht und sollten so auch nicht verwendet werden. Unions sind dafür gedacht, mehrere exklusive Informationen in ein und demselben Speicherbereich unterzubringen. Ich bin mir momentan gar nicht sicher, ob dies so explizit im Standard formuliert wird, aber eine alte Richtlinie besagt, man soll lesend nur auf das Element einer Union zugreifen, welches zuletzt geschrieben wurde.
 
Ups, völlig übersehen. Dann hatte mich mein Gedächtnis doch nicht ganz getrübt, dass der Zugriff sogar vom Standard definiert wird. :)
 
Zurück
Oben