Jak zaokrąglić wynik dzielenia liczb całkowitych?
Myślę w szczególności o tym, jak wyświetlać kontrolki paginacji, używając języka takiego jak C # lub Java.
Jeśli mam x elementy, które chcę wyświetlić w kawałkach y na stronę, ile stron będzie potrzebnych?
15 answers
Znalazłem eleganckie rozwiązanie:
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 13:42:08
Konwersja na zmiennoprzecinkową i wsteczną wydaje się ogromną stratą czasu na poziomie procesora.
Rozwiązanie Iana Nelsona:
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;
Można uprościć do:
int pageCount = (records - 1) / recordsPerPage + 1;
AFAICS, to nie ma błędu przepełnienia, który Brandon DuRette wskazał, a ponieważ używa go tylko raz, nie musisz przechowywać recordspepage specjalnie, jeśli pochodzi z drogiej funkcji, aby pobrać wartość z pliku konfiguracyjnego lub czegoś takiego.
Tzn. może to być nieefektywne, jeśli config.fetch_value użyło wyszukiwania bazy danych lub czegoś takiego:
int pageCount = (records + config.fetch_value('records per page') - 1) / config.fetch_value('records per page');
To tworzy zmienną, której tak naprawdę nie potrzebujesz, która prawdopodobnie ma (drobne) implikacje pamięci i jest po prostu zbyt wiele wpisywania:
int recordsPerPage = config.fetch_value('records per page')
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;
To wszystko jest jedną linią i pobiera dane tylko raz:
int pageCount = (records - 1) / config.fetch_value('records per page') + 1;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-02 13:26:00
To powinno dać ci to, czego chcesz. Na pewno będziesz chciał x elementów podzielonych przez Y elementów na stronie, problem jest, gdy pojawiają się nierówne liczby, więc jeśli istnieje częściowa strona, chcemy również dodać jedną stronę.
int x = number_of_items;
int y = items_per_page;
// with out library
int pages = x/y + (x % y > 0 ? 1 : 0)
// with library
int pages = (int)Math.Ceiling((double)x / (double)y);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 13:39:51
W C# rozwiązaniem jest rzut wartości do dwójki (jak Math.Sufit zajmuje podwójne):
int nPages = (int)Math.Ceiling((double)nItems / (double)nItemsPerPage);
W Javie powinieneś zrobić to samo z matematyką.ceil ().
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-29 21:24:08
Rozwiązanie integer math dostarczone przez Iana jest ładne, ale cierpi na błąd integer overflow. Przy założeniu, że wszystkie zmienne są int
, rozwiązanie można przepisać tak, aby używać long
matematyki i uniknąć błędu:
int pageCount = (-1L + records + recordsPerPage) / recordsPerPage;
Jeśli records
jest long
, błąd pozostaje. Rozwiązanie modułu nie ma błędu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-31 06:51:57
Wariant odpowiedzi Nicka Berardiego, który unika gałęzi:
int q = records / recordsPerPage, r = records % recordsPerPage;
int pageCount = q - (-r >> (Integer.SIZE - 1));
Uwaga: (-r >> (Integer.SIZE - 1))
składa się z bitu znaku r
, Powtórzonego 32 razy (dzięki rozszerzeniu znaku operatora >>
.) Wartość ta wynosi 0, Jeśli r
jest równa zero lub ujemna, -1, jeśli r
jest dodatnia. Zatem odejmowanie od q
powoduje dodanie 1 if records % recordsPerPage > 0
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:45
Dla rekordów = = 0, rozwiązanie rjmunro daje 1. Poprawnym rozwiązaniem jest 0. To powiedziawszy, jeśli wiesz, że rekordy > 0 (i jestem pewien, że wszyscy założyliśmy recordspepage > 0), To rozwiązanie rjmunro daje prawidłowe wyniki i nie ma żadnych problemów z przepełnieniem.
int pageCount = 0;
if (records > 0)
{
pageCount = (((records - 1) / recordsPerPage) + 1);
}
// no else required
Wszystkie całkowe rozwiązania matematyczne będą bardziej wydajne niż dowolne z rozwiązań zmiennoprzecinkowych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-11 10:41:28
In need of an extension method:
public static int DivideUp(this int dividend, int divisor)
{
return (dividend + (divisor - 1)) / divisor;
}
Brak tu sprawdzeń (przepełnienie, DivideByZero
, itp.), możesz dodać, jeśli chcesz. Nawiasem mówiąc, dla tych, którzy martwią się o wywołanie metody, proste funkcje takie jak ta mogą być i tak wbudowane przez kompilator, więc nie sądzę, że o to chodzi. Zdrowie.
P. S. może się okazać przydatne, aby być tego świadomym (dostaje resztę):
int remainder;
int result = Math.DivRem(dividend, divisor, out remainder);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-15 19:52:17
Inną alternatywą jest użycie funkcji mod () (lub'%'). Jeśli istnieje niezerowa reszta, zwiększ liczbę całkowitą wyniku dzielenia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 13:30:43
Wykonuję następujące czynności, obsługuję wszelkie przelewy:
var totalPages = totalResults.IsDivisble(recordsperpage) ? totalResults/(recordsperpage) : totalResults/(recordsperpage) + 1;
I użyj tego rozszerzenia, jeśli jest 0 wyników:
public static bool IsDivisble(this int x, int n)
{
return (x%n) == 0;
}
Również dla bieżącego numeru strony (nie był pytany, ale może być przydatny):
var currentPage = (int) Math.Ceiling(recordsperpage/(double) recordsperpage) + 1;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 09:36:58
Alternatywa dla usunięcia rozgałęzienia w testowaniu dla zera:
int pageCount = (records + recordsPerPage - 1) / recordsPerPage * (records != 0);
Nie wiem czy to zadziała w C#, powinno działać w C / C++.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-13 03:26:08
Metoda ogólna, której wynik można iterować może być interesująca:
public static Object[][] chunk(Object[] src, int chunkSize) {
int overflow = src.length%chunkSize;
int numChunks = (src.length/chunkSize) + (overflow>0?1:0);
Object[][] dest = new Object[numChunks][];
for (int i=0; i<numChunks; i++) {
dest[i] = new Object[ (i<numChunks-1 || overflow==0) ? chunkSize : overflow ];
System.arraycopy(src, i*chunkSize, dest[i], 0, dest[i].length);
}
return dest;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-28 14:09:15
Miałem podobną potrzebę, w której musiałem przekonwertować minuty na godziny i minuty. Użyłem:
int hrs = 0; int mins = 0;
float tm = totalmins;
if ( tm > 60 ) ( hrs = (int) (tm / 60);
mins = (int) (tm - (hrs * 60));
System.out.println("Total time in Hours & Minutes = " + hrs + ":" + mins);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-19 17:06:05
Poniższe powinny robić zaokrąglenia lepiej niż powyższe rozwiązania, ale kosztem wydajności (ze względu na obliczanie zmiennoprzecinkowe 0,5*rctDenominator):
uint64_t integerDivide( const uint64_t& rctNumerator, const uint64_t& rctDenominator )
{
// Ensure .5 upwards is rounded up (otherwise integer division just truncates - ie gives no remainder)
return (rctDenominator == 0) ? 0 : (rctNumerator + (int)(0.5*rctDenominator)) / rctDenominator;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 15:21:15
Będziesz chciał dokonać podziału zmiennoprzecinkowego, a następnie użyć funkcji sufit, aby zaokrąglić wartość do następnej liczby całkowitej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 13:29:57