Witam,
w jaki sposób mogę obliczyć w C podłogę i sufit podanej liczby bez używania funkcji znanych z biblioteki C++ floor, ceil ?
Jakiś krótki algorytm który polecacie ?
Witam,
w jaki sposób mogę obliczyć w C podłogę i sufit podanej liczby bez używania funkcji znanych z biblioteki C++ floor, ceil ?
Jakiś krótki algorytm który polecacie ?
podłoga - konwersja na int'a
sufit:
podloga(x)+(podloga(x)!=x);
podloga(x)+(podloga(x)!=x?((x>0)-(x<0)):0);
Nie za bardzo rozumiem, może powoli:
Podłoga-
zadeklarowaną zmienną float rzutować na inta ?
Na zasadzie:
float a=(int)b
?
O to Ci chodzi ?
Tego przykładu z podłogą niestety w ogóle nie rozumiem ;/
Czy mógłyś podać przykład ?
Podłoga to rzutowanie na typ całkowitoliczbowy czyli obcięcie części ułamkowej. Możesz go sobie znowu zrzutować na liczbę zmiennoprzecinkową - nie ma z tym problemu.
Sufit w tej pierwotnej wersji wyżej, to podłoga plus 1, o ile podłoga nie jest równa liczbie początkowej. Jeżeli jest równa to wtedy nie dodaje się nic (a konkretnie to dodaje się 0). To w nawiasie to warunek, który ma wartość logiczną - w reprezentacji liczbowej będzie to 1 albo 0. (!=
to operator "nie równa się", ale to chyba wiesz?)
Niestety metody te w ogóle nie działają dla liczb ujemnych (dlatego zostały już poprawione, zobacz wyżej).
A coś co działa także dla ujemnych ?
Szukam, szukam ale nie mogę za cholerę znaleźć.
Ja rozwiązałbym to tak (to w zasadzie rozszerzenie pomysłu @_13th_Dragon z tym !=
):
Podłoga:
int Floor(double x) {
const int int_part = (int)x;
if (int_part >= 0) {
return int_part;
} else {
return int_part - (x != int_part);
}
}
Sufit:
int Ceil(double x) {
const int int_part = (int)x;
if (int_part < 0) {
return int_part;
} else {
return int_part + (x != int_part);
}
}
Można zauważyć, że funkcje różnią się jedynie porównaniem i znakiem działania. Są do siebie na tyle podobne, że w C++ (w C też) można zmajstrować takie monstrum:
int floorCeilImpl(const std::function<bool (int, int)> &comparator,
const std::function<int (int, int)> &operation,
double x) {
const int int_part = static_cast<int>(x);
if (comparator(int_part, 0)) {
return int_part;
} else {
return operation(int_part, (x != int_part));
}
}
int floor(double x) {
return floorCeilImpl(std::greater_equal<int>(), std::minus<int>(), x);
}
int ceil(double x) {
return floorCeilImpl(std::less<int>(), std::plus<int>(), x);
}
http://ideone.com/1X13Kp (:-D) - wygląda strasznie, ale optymalizuje się chyba do wersji takiej jak ta "zwyczajna" wyżej.