W C++, załóżmy, że mam numer x
typu T
, który może być typem całkowitym lub zmiennoprzecinkowym. Chcę znaleźć największy numer y
typu T
, dla którego jest przechowywany y < x
. Rozwiązanie musi być szablonowe, aby działało w sposób przezroczysty zarówno dla liczb całkowitych, jak i liczb zmiennoprzecinkowych. Możesz zignorować przypadek krawędzi, gdzie x
jest już najmniejszą liczbą, która może być reprezentowana w T
.Największa liczba <x?
ewentualnego wykorzystania CASE: To pytanie zostało oznaczone jako zbyt zlokalizowane, stąd chciałbym zapewnić przypadek użycia, który moim zdaniem jest bardziej ogólne. Zauważ, że nie jestem oryginalnym autorem OP.
Rozważmy następujący wzór:
struct lower_bound {
lower_bound(double value, bool open) : value(open? value+0.1 : value) {}
double value;
bool operator()(double x) { return x >= value; }
};
Klasa symuluje dolnej granicy, która może być albo otwarte albo zamknięte. Oczywiście w rzeczywistym (kalamburowym) życiu nie możemy tego zrobić. Przepływ jest niemożliwy (lub przynajmniej dość trudny) do obliczenia dla S będąc wszystkimi liczbami rzeczywistymi.
Jednak gdy S jest zbiorem liczb zmiennoprzecinkowych, jest to bardzo ważna zasada, ponieważ mamy do czynienia z zasadniczo na zbiór przeliczalny; a następnie nie ma czegoś takiego jak otwarta lub zamknięta granica. Oznacza to, że> = można zdefiniować w kategoriach> like done w klasie lower_bound.
Dla uproszczenia kodu użyłem +0.1 do symulacji otwartej dolnej granicy. Oczywiście 0,1 jest wartością surową, ponieważ mogą występować wartości z takie, że wartość jest równa < z < = wartość + 0,1 lub wartość + 0,1 == wartość reprezentacji zmiennoprzecinkowej. Stąd @ Brett-hale Odpowiedź jest bardzo przydatna :)
Możesz pomyśleć o innym prostsze rozwiązanie:
struct lower_bound {
lower_bound(double value, bool open) : open(open), value(value) {}
bool open;
double value;
bool operator()(double x) { return (open ? x > value : x>=value); }
};
Jest to jednak mniej skuteczne jako sizeof (LOWER_BOUND) jest większa, i operator() musi wykonać bardziej skomplikowaną instrukcję. Pierwsza implementacja jest naprawdę wydajna i może być implementowana po prostu jako podwójna, a nie jako struktura. Z technicznego punktu widzenia jedynym powodem skorzystania z drugiej implementacji jest to, że zakłada się, że podwójne jest ciągłe, podczas gdy nie jest i wydaje mi się, że nie będzie nigdzie w najbliższej przyszłości.
Mam nadzieję, że stworzyłem i wyjaśniłem ważny przypadek użycia i że nie obraziłem pierwotnego autora.
można dać przykład, co byłoby dla pływających typy punktów? Czy to oznacza, że mantyka y jest mniejsza o jeden bit, a wykładnik jest taki sam? – angelatlarge
Oczekuję więcej od użytkownika 27,5 tys. –
Czy ... próbowałeś czegoś? – Rapptz