Znajdź min / max pływaka / podwójnego, który ma taką samą reprezentację wewnętrzną
Odświeżaniepunkty zmiennoprzecinkowe (równieżPDF), IEEE-754 i udziałw tej dyskusji na temat zaokrąglania zmiennoprzecinkowego podczas konwersji na łańcuchy, doprowadził mnie do majsterkowania: jak mogę uzyskać maksymalną i minimalną wartość dla danej liczby zmiennoprzecinkowej, której reprezentacje binarne są równe.
Zrzeczenie się: w tej dyskusji lubię trzymać się 32-bitowego i 64-bitowego zmiennoprzecinkowego, jak opisuje IEEE-754. Nie interesuje mnie rozszerzony zmiennoprzecinkowy (80 bitów) ani quady (128 bitów IEEE-754-2008) ani żaden inny standard (IEEE-854).
tło: Komputery są złe w reprezentowaniu0.1
w reprezentacji binarnej. W C # float reprezentuje to jako3DCCCCCD
wewnętrznie (C # używa round-to-najbliższego) i double as3FB999999999999A
. Te same wzory bitów są używane do dziesiętnego0.100000005
(float) i0.1000000000000000124
(podwójnie), ale nie dla0.1000000000000000144
(podwójnie).
Dla wygody następujący kod C # podaje te wewnętrzne reprezentacje:
string GetHex(float f)
{
return BitConverter.ToUInt32(BitConverter.GetBytes(f), 0).ToString("X");
}
string GetHex(double d)
{
return BitConverter.ToUInt64(BitConverter.GetBytes(d), 0).ToString("X");
}
// float
Console.WriteLine(GetHex(0.1F));
// double
Console.WriteLine(GetHex(0.1));
W przypadku0.1
, nie ma niższej liczby dziesiętnej, która jest reprezentowana przez ten sam wzór bitowy0.99...99
dostarczy inną reprezentację bitów (tj. float dla0.999999937
plony3F7FFFFF
wewnętrznie).
Moje pytanie jest proste: jak mogę znaleźć najniższą i najwyższą wartość dziesiętną dla danego pływaka (lub podwójnego), który jest wewnętrznie przechowywany w tej samej reprezentacji binarnej.
Czemu: (Wiem, że poprosisz), aby znaleźć błąd w zaokrąglaniu w .NET, kiedy konwertuje on na ciąg znaków i kiedy konwertuje z ciągu znaków, aby znaleźć dokładną wartość wewnętrzną i lepiej zrozumieć własne błędy zaokrąglania.
Domyślam się, że to: weź mantysę, usuń resztę, zdobądź jej dokładną wartość, weź jedną (mantysę) wyższą i oblicz średnią: wszystko poniżej, które da ten sam wzór bitowy. Moim głównym problemem jest: jak uzyskać część ułamkową jako liczbę całkowitą (manipulacja bitem to nie mój najsilniejszy atut).DoubleConverter Jona Skeeta klasa może być pomocna.