Zastanawiam się tylko, czy chcę podzielić a przez b i interesuje mnie zarówno wynik c, jak i reszta (np. Powiedz, że mam liczbę sekund i chcę to podzielić na minuty i sekundy), jaki jest najlepszy sposób, aby zająć się tym?
Czy może być
int c = (int)a / b;
int d = a % b;
lub
int c = (int)a / b;
int d = a - b * c;
lub
double tmp = a / b;
int c = (int)tmp;
int d = (int)(0.5+(tmp-c)*b);
lub
może istnieje magiczna funkcja, która daje jedno i drugie na raz?
double
(twoim ostatnim przedmiotem) wydaje mi się złym pomysłem, skończysz z liczbami, które się nie zgadzają i mogą kosztować cię wydajność i rozmiar pliku wykonywalnego (zawsze był to problem w niektórych systemach wbudowanych).Odpowiedzi:
Na x86 reszta jest produktem ubocznym samego dzielenia, więc każdy w połowie przyzwoity kompilator powinien być w stanie po prostu go użyć (i nie wykonywać
div
ponownie). Prawdopodobnie dzieje się tak również na innych architekturach.źródło
idivl
instrukcji i używając wyników w eax i edx. Byłbym zszokowany, gdyby tak się nie stało.idivl
instrukcje, ale z-O1
lub większym otrzymujesz jedną. Jak mówi podręcznik: „Bez opcji optymalizacji… Instrukcje są niezależne” .std::div
zwraca strukturę zawierającą zarówno wynik, jak i resztę.źródło
long long
, ale jest bardzo prawdopodobne, że Twój kompilator malong long
przeciążeniestd::div
jako rozszerzenie.Przynajmniej na x86 g ++ 4.6.1 po prostu używa IDIVL i pobiera oba z tej pojedynczej instrukcji.
Kod C ++:
Kod x86:
źródło
/=
- może być konieczne użycie zmiennej tymczasowej, aby najpierw zachować dzielenie.Przykładowy kod testujący div () i połączony podział i mod. Skompilowałem je za pomocą gcc -O3, musiałem dodać wywołanie doNothing, aby zatrzymać kompilator przed optymalizacją wszystkiego (wyjście byłoby 0 dla rozwiązania dzielenia + mod).
Dodaj szczyptę soli:
Wyjścia: 150
Wyjścia: 25
źródło
Oprócz wspomnianego std :: div rodziny funkcji, istnieje również std :: remquo rodzina funkcji, zwróci rem -ainder i uzyskiwanie quo -tient za pośrednictwem przekazywane w wskaźnika.
[Edytuj:] Wygląda na to, że std :: remquo w rzeczywistości nie zwraca ilorazu .
źródło
Mając wszystko inne na równi, najlepszym rozwiązaniem jest takie, które jasno wyraża Twoje zamiary. Więc:
jest prawdopodobnie najlepszą z trzech przedstawionych przez Ciebie opcji. Jak zauważono w innych odpowiedziach,
div
metoda obliczy dla Ciebie obie wartości naraz.źródło
Nie możesz ufać g ++ 4.6.3 tutaj z 64-bitowymi liczbami całkowitymi na 32-bitowej platformie Intel. a / b jest obliczane przez wywołanie divdi3, a% b jest obliczane przez wywołanie moddi3. Mogę nawet wymyślić przykład, który oblicza a / b i ab * (a / b) z tymi wywołaniami. Więc używam c = a / b i ab * c.
Metoda div wywołuje funkcję, która oblicza strukturę div, ale wywołanie funkcji wydaje się nieefektywne na platformach, które mają sprzętową obsługę typu integralnego (tj. 64-bitowe liczby całkowite na 64-bitowych platformach intel / amd).
źródło
Możesz użyć modułu, aby uzyskać resztę. Chociaż odpowiedź @ cnicutar wydaje się czystsza / bardziej bezpośrednia.
źródło