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
Der Test:
Spoiler anzeigen
Herzlichen Dank...
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:
C#-Quellcode
- public static double GetDouble(string value)
- {
- double resultA = .0;
- double resultB = .0;
- string[] binStructs = new string[3];
- binStructs[0] = value.Substring(0, 1);
- binStructs[1] = value.Substring(1, 32);
- binStructs[2] = value.Substring(33, 8);
- bool isSigned = binStructs[0] == "0";
- char[] reversedArray = binStructs[1].ToCharArray();
- Array.Reverse(reversedArray);
- for (int i = 0; i < reversedArray.Length; i++)
- {
- double n = double.Parse(reversedArray[i] + "");
- resultA += n * Math.Pow(2, i);
- }
- reversedArray = binStructs[2].ToCharArray();
- Array.Reverse(reversedArray);
- for (int i = 0; i < reversedArray.Length; i++)
- {
- double n = double.Parse(reversedArray[i] + "");
- resultB += n * Math.Pow(2, i);
- }
- resultA *= isSigned ? -1 : 1;
- return resultA * Math.Pow(10, -resultB);
- }
- public static string GetBinary(double value)
- {
- string fullBin = "";
- string valueString = value.ToString("F99").Trim('0').Replace('.', ','); // aus: https://stackoverflow.com/a/7032578/9816636
- if (value == 0)
- valueString = "0,0";
- string[] splittedDecimal = valueString.Split(',');
- int numE = splittedDecimal[1].Length;
- value = value * Math.Pow(10, numE);
- int data = (int)value;
- for (int i = 0; i < 8; i++)
- {
- if (numE % 2 == 0)
- fullBin += "0";
- else fullBin += "1";
- numE /= 2;
- }
- for (int i = 0; i < 32; i++)
- {
- if (data % 2 == 0)
- fullBin += "0";
- else fullBin += "1";
- data /= 2;
- }
- if (value < 0)
- fullBin += "0";
- else fullBin += "1";
- char[] reversedArray = fullBin.ToCharArray();
- Array.Reverse(reversedArray);
- return new string(reversedArray);
- }
Der Test:
C#-Quellcode
- static void Main(string[] args)
- {
- Random r = new Random();
- int error = 0;
- for (int i = 0; i < 10000; i++)
- {
- double a = Math.Round(r.NextDouble(), 5);
- double b = Math.Round(GetDouble(GetBinary(a)), 5);
- if (a != b)
- {
- error++;
- Console.WriteLine(a + " != " + b);
- }
- }
- double accuracy = 1.0 - (error / 10000.0d);
- accuracy *= 100;
- Console.WriteLine("Accuracy= " + accuracy + "%");
- Console.ReadLine();
- }
Herzlichen Dank...
Und Gott alleine weiß alles am allerbesten und besser.