convert double to long int



  • Hallo,

    ich würde gerne folgende C#-Zeile in C schreiben, was mir nicht gelingt

    foo(double value) // hier wird 0.2240070104599 übergeben
    {
          return foo1(*(long*)(&value));
    }
    

    nach foo1 wird dann 4597238723401220096 bzw. 0x3FCCAC4300000000 übergeben

    mir ist nicht ganz klar was da passiert, einer normaler cast nach long int wird da wohl nicht zum Ziel führen, hat jemand Ideen?

    Grüße



  • Das wird die Speicherstelle ein double-Variable als Speicherstelle einer long-Variable interpretiert und eben dieser long-Wert an die Funktion foo1 übergeben.
    Der Rückgabewert dieser (hier unbekannten) Funktion foo1 wird auch von foo zurück gegeben.

    Folgende Probleme können auftreten:
    sizeof(double) ist meist 8
    sizeof(long) ist häufig 4, manchmal 8

    C# ist mir unbekannt

    Was soll deiner Meinung nach mit den 0.2240070104599 passieren, damit du zufrieden bist?
    Welches Ergebnis erwartest du?



  • zufrieden bin ich, wenn aus 0.2240.. die Zahl 0x3FCCAC4300000000 wird
    und ich dann noch verstehe wie das funktioniert

    ich kann auch gerne den restlichen Code posten, aber ich dachte mir das war das Wichigste

    double value ist die 0.2240...

    public unsafe static byte[] GetBytes(double value)
    		{
    			return BitConverter.GetBytes(*(long*)(&value));
    		}
    

    long value ist nun 0x3FCCAC4300000000

    public unsafe static byte[] GetBytes(long value)
    		{
    			byte[] array = new byte[8];
    			fixed (byte* ptr = array)
    			{
    				*(long*)ptr = value;
    			}
    			return array;
    		}
    


  • Du möchtest also die interne Darstellung vom double haben?

    Ok. Ich habe gerade gesehen, das in C# long 64-Bit ist.

    Da musst du bei C dann int64_t (bzw. long long ) nehmen.

    Oder du nimmst ein unsigned char Array.

    Eine union ist zwar nicht vom Standard gedeckt, geht aber auch.

    union datatypes {
     double  d;
     int64_t i64;
     uint8_t u8[8];
    }
    


  • stimmt Dirk, darauf bin ich auch gerade gekommen, Gleitkommadarstellung mit double precision, damit komme ich genau auf den Wert.
    64Bit long long kann mein Compiler nicht, der ist noch vom alten Schlag 😃

    wie meinst du das mit dem chararray?



  • wenn ich das mal fix in ideone teste gehts mit einem float

    #include <stdio.h>
    
    int main(void)
    {
      float f = 0.2240070104599;
    
      printf ("f: %x\n", *(unsigned long long int *)&f);
    }
    
    Success	time: 0 memory: 2168 signal:0
    
    f: 3e656218
    

    mit double aber nicht

    #include <stdio.h>
    
    int main(void)
    {
      double f = 0.2240070104599;
    
      printf ("f: %x\n", *(unsigned long long int *)&f);
    }
    
    Success	time: 0 memory: 2168 signal:0
    f: 4
    

    😕



  • Regenschirm schrieb:

    wie meinst du das mit dem chararray?

    Acht Byte hintereinander weg.
    Da kannst du dann einzeln drauf zugreifen.

    for(unsigned char *p= (unsigned char*)&f, int i=sizeof(f)-1; i>=0; i--)
      printf("%02x",p[i]);
    

    Regenschirm schrieb:

    wenn ich das mal fix in ideone teste gehts mit einem float

    Das ist Müll, da ein float i.A. nur 4 Byte braucht.
    In diesem Fall funktioniert das noch, weil wohl die Endianess stimmt.

    Regenschirm schrieb:

    mit double aber nicht

    Das ist Müll, weil %x der falsche Formatspecifier für long long ist.



  • super hat mich weiter gebracht, danke



  • Regenschirm schrieb:

    ich würde gerne folgende C#-Zeile in C schreiben, was mir nicht gelingt

    foo(double value) // hier wird 0.2240070104599 übergeben
    {
          return foo1(*(long*)(&value));
    }
    

    Das ist gültiger C Code, vor foo fehlt noch long und foo1 sollte ebenso funktionieren.
    Ich glaube, dein C# Code ist schon Müll, was du willst ist offensichtlich ein Hexdump deines double-Speichers und nicht - wie dein Titel aussagt - eine "Konvertierung" des double-Wertes in einen long-Wert (die sowieso ziemlich sinnfrei ist, da Kommastellen entfallen und oft ein long-Überlauf zu erwarten ist).


Anmelden zum Antworten