[C#] Binary Repräsentation einer Fließkommazahl

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von Bluespide.

    [C#] Binary Repräsentation einer Fließkommazahl

    Hallo,

    ich versuche gerade eine Fließkommazahl zu approximieren um es binär zu repräsentieren.

    Algorithmus funktioniert folgendergestalt:

    Input sei exemplarisch: 2,11551

    Zu einem String konvertieren, splitten bei ',' die Länge der Kommazahlen ermitteln (.Length),
    Original-Input multiplizieren mit 10^AnzahlKommaStellen

    Bit Repräsentation Schema:

    1 11111111111111111111111111111111 11111111

    Das erste Segment ist das Vorzeichen,
    das zweite die Mantisse, das letzte Segment ist der Exponent mit dem die Basis 10 exponiert, welche dann abschließend mit der Mantisse multipliziert wird.

    Funktioniert alles, nur gibt es immer winzige Abweichungen:



    Wieso?

    Liegt das daran das ich irgendwo kurz die Zahl in ein Integer caste?

    Der Code:

    Spoiler anzeigen

    C#-Quellcode

    1. public static double GetDouble(string value)
    2. {
    3. double resultA = .0;
    4. double resultB = .0;
    5. string[] binStructs = new string[3];
    6. binStructs[0] = value.Substring(0, 1);
    7. binStructs[1] = value.Substring(1, 32);
    8. binStructs[2] = value.Substring(33, 8);
    9. bool isSigned = binStructs[0] == "0";
    10. char[] reversedArray = binStructs[1].ToCharArray();
    11. Array.Reverse(reversedArray);
    12. for (int i = 0; i < reversedArray.Length; i++)
    13. {
    14. double n = double.Parse(reversedArray[i] + "");
    15. resultA += n * Math.Pow(2, i);
    16. }
    17. reversedArray = binStructs[2].ToCharArray();
    18. Array.Reverse(reversedArray);
    19. for (int i = 0; i < reversedArray.Length; i++)
    20. {
    21. double n = double.Parse(reversedArray[i] + "");
    22. resultB += n * Math.Pow(2, i);
    23. }
    24. resultA *= isSigned ? -1 : 1;
    25. return resultA * Math.Pow(10, -resultB);
    26. }
    27. public static string GetBinary(double value)
    28. {
    29. string fullBin = "";
    30. string valueString = value.ToString("F99").Trim('0').Replace('.', ','); // aus: https://stackoverflow.com/a/7032578/9816636
    31. if (value == 0)
    32. valueString = "0,0";
    33. string[] splittedDecimal = valueString.Split(',');
    34. int numE = splittedDecimal[1].Length;
    35. value = value * Math.Pow(10, numE);
    36. int data = (int)value;
    37. for (int i = 0; i < 8; i++)
    38. {
    39. if (numE % 2 == 0)
    40. fullBin += "0";
    41. else fullBin += "1";
    42. numE /= 2;
    43. }
    44. for (int i = 0; i < 32; i++)
    45. {
    46. if (data % 2 == 0)
    47. fullBin += "0";
    48. else fullBin += "1";
    49. data /= 2;
    50. }
    51. if (value < 0)
    52. fullBin += "0";
    53. else fullBin += "1";
    54. char[] reversedArray = fullBin.ToCharArray();
    55. Array.Reverse(reversedArray);
    56. return new string(reversedArray);
    57. }



    Der Test:

    Spoiler anzeigen

    C#-Quellcode

    1. static void Main(string[] args)
    2. {
    3. Random r = new Random();
    4. int error = 0;
    5. for (int i = 0; i < 10000; i++)
    6. {
    7. double a = Math.Round(r.NextDouble(), 5);
    8. double b = Math.Round(GetDouble(GetBinary(a)), 5);
    9. if (a != b)
    10. {
    11. error++;
    12. Console.WriteLine(a + " != " + b);
    13. }
    14. }
    15. double accuracy = 1.0 - (error / 10000.0d);
    16. accuracy *= 100;
    17. Console.WriteLine("Accuracy= " + accuracy + "%");
    18. Console.ReadLine();
    19. }


    Herzlichen Dank...
    Und Gott alleine weiß alles am allerbesten und besser.