Konvertierung von Integer zu Float (zu ungenau ..)

  • VB.NET
  • .NET (FX) 1.0–2.0

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von Eierlein.

    Konvertierung von Integer zu Float (zu ungenau ..)

    Hallo

    Ich habe einen Integer mit dem Wert 1068719552 und umgewandelt in Float ist der Wert 1.401298523.
    Nun habe ich aber das Problem, dass meine Funktion IntegerToSingle drei Nachkommastellen weglässt.

    VB.NET-Quellcode

    1. Public Function IntegerToSingle(Value As Integer)
    2. Return BitConverter.ToSingle(BitConverter.GetBytes(Value), 0)
    3. End Function


    Wenn ich die Zahl nun umwandeln lasse, kommt dabei 1.401299 raus und nicht 1.401298523 .. Das ist ein Problem, weil ich es so genau wie möglich brauche.

    Weiß jemand wie ich die Zahl korrekt umwandeln kann? :)
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Vultrax“ ()

    Mal eine andere Frage. Was genau ist der Sinn dahinter? Verwende doch gleich die Bytes.
    Ich habe mal folgendes probiert:

    C#-Quellcode

    1. ​class Program
    2. {
    3. static void Main(string[] args)
    4. {
    5. Foo foo = new Foo();
    6. foo.Integer = 1068719552;
    7. Console.WriteLine("Int > Float: " + foo.Float);
    8. foo.Long = 1068719552;
    9. Console.WriteLine("Long > Double: " + foo.Double);
    10. Console.ReadKey();
    11. }
    12. }
    13. [StructLayout(LayoutKind.Explicit)]
    14. struct Foo
    15. {
    16. [FieldOffset(0)]
    17. public int Integer;
    18. [FieldOffset(0)]
    19. public float Float;
    20. [FieldOffset(0)]
    21. public long Long;
    22. [FieldOffset(0)]
    23. public double Double;
    24. }


    Das interessante ist, dass die Ausgabe folgendes ist:

    Quellcode

    1. ​Int > Float: 1,401299
    2. Long > Double: 5,28017615682048E-315


    Haut man jedoch mal einen Breakpoint rein so sieht man dieses:

    Wieso, weshalb? Keine Ahnung. Habe leider keine Zeit um zu suchen. Habe diverse Formate bereits ausprobiert. Immer mit dem selben Resultat.
    Würde mich aber interessieren ;).


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „thefiloe“ ()

    Vultrax schrieb:

    drei Nachkommastellen
    Integer hat keine Nachkommastellen.
    Nimm Double statt Single.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @thefiloe Ich würde behaupten das da ToString aufgerufen wird und das Default nur 6 Nachkommastellen ausgibt.
    Dabei evtl. interessant: stackoverflow.com/questions/14…les-for-output-in-c-sharp
    Wobei natürlich die Frage ist, ob das hier in dem Fall genauso auch für Floats zutrifft. Scheint aber, als wäre das dann somit .NET-intern so, egal, was man an Formatting-Zeugs angibt.
    Man könnte das ja mal in einer nativen Sprache testen, was da in diesem Fall hier passieren würde.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    thefiloe schrieb:

    überhaupt gelesen
    So was:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim int As Integer = 1068719552
    3. Dim flt As Single = int
    4. Dim dbl As Double = int
    5. MessageBox.Show(int.ToString & Environment.NewLine & flt.ToString & Environment.NewLine & dbl.ToString)
    6. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @slice das liegt wohl auf der Hand. Meine Frage war wie man das umgeht.
    Und @RodFromGermany, nein das ist eben nicht die Fragestellung. Das wäre nichts als casten. Der TE will nicht den Wert casten sondern der Speicher der hinter dem Wert steht.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    thefiloe schrieb:

    das ist eben nicht die Fragestellung.

    Vultrax schrieb:

    Weiß jemand wie ich die Zahl korrekt umwandeln kann?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Vultrax schrieb:

    Ich habe einen Integer mit dem Wert 1068719552 und umgewandelt in Float ist der Wert 1.401298523.

    Wenn das, das gewünschte Ergebnis ist, dann hat das mit dem was du machst, nämlich normal casten, wenig zu tun.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    Vultrax schrieb:

    Ich habe einen Integer mit dem Wert 1068719552 und umgewandelt in Float ist der Wert 1.401298523.
    Nun habe ich aber das Problem, dass meine Funktion IntegerToSingle drei Nachkommastellen weglässt.
    Offensichtlich unterscheidet sich die Umwandlung (wie auch immer die vonstatten geht) von der Umwandlung mittels deiner IntegerToSingle() - Methode.
    Denn mal kommt ja 1.401298523 bei raus, und mal 1.401299.

    Nun wäre nützlich, die andere Umwandlungs-Methode auch kennenzulernen.
    Was ich mir auch vorstellen kann, ist, dass es sich um ein Darstellung-Problem handelt - etwa dass die Zahlen schon identisch sind, nur dasses dem Debugger halt zu doof ist, alle 9 Nachkommastellen anzuzeigen.

    ErfinderDesRades schrieb:

    Was ich mir auch vorstellen kann, ist, dass es sich um ein Darstellung-Problem handelt - etwa dass die Zahlen schon identisch sind, nur dasses dem Debugger halt zu doof ist, alle 9 Nachkommastellen anzuzeigen.

    Ich gehe davon aus, dass es ein Darstellungsproblem ist, da ich es mit meinem Code exakt reproduzieren kann (obwohl ich einen anderen Code verwende). Nur ist es genau umgekehrt. Der Debugger zeigt mir alle Kommastellen an, sobald ich jedoch einen String draus machen will treten die Ungenauigkeiten auf.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    @thefiloe Die Frage ist doch, woe numerische Werte im Speicher abgelegt werden.
    Zuerst mal sind ein Integer und ein Single 4 Byte lang, ein Long und ein Double sind 8 Byte lang.
    Wenn Du in Deine Foo-Struktur 4 Byte reintust und 8 Byte rausholst, sind die niederwertigen Bytes Reste der letzten Operation, also praktisch Zufallszahlen, sie sollten also vorher gelöscht werden.
    Dann sind Single / Double aufgebaut als n Bit Exponent und m Bit Mantisse und ein Bit Vorzeichen (n+m=31 bzw. n+m=63), die Aufteilung weiß ich jetzt nicht auswendig.
    Experimentell kannst Du das rauskriegen: Wenn Du das LSB des Exponenten mit Überlauf inkrementierst, verdoppelt sich der numerische Wert.
    Der Arithmetik-CoProzessor arbeitet intern mit 80 Bit, dafür gibt es in C++ long double, womit die Prozessorbreite ausgereizt wird (das vermisse ich gelegentlich in .NET).
    ----
    Wenn Du Deine Foo-Struktur unter diesem Gesichtspunkt betrachtest, ist das äquivalent zum Schreiben chinesischer Lautzeichen mit lateinischen Buchstaben und dem Versuch, das als Deutsch zu interpretieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    EDR: OK.
    Gonger: Jou.

    ErfinderDesRades schrieb:

    problematisch
    Dies hier macht er "korrekt":

    VB.NET-Quellcode

    1. Dim sng = 1.40129852F
    2. Dim sng2 = sng ' selber Wert
    3. Dim s = sng.ToString("n9")

    Wenn Ihr versucht, da mehr Ziffern einzugeben:

    werden die von der IDE abgeschnitten.
    Das eigentliche Problem ist, dass Single nur etwa 7,5 signifikante Ziffern hat. Der genaue Wert hängt vom numerischen Wert der Zahl ab.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vielen Dank an alle hier! :)

    @Gonger96 Genauso wollte ich es (soweit) haben, allerdings ist mir aufgefallen das auch mit G9 die letzte Zahl (3) weggelassen wird und G10 geht ja nicht.
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford