Java 8 memiliki Math.floorMod, tetapi sangat lambat (implementasinya memiliki beberapa divisi, perkalian, dan bersyarat). Mungkin saja JVM memiliki rintisan yang dioptimalkan secara intrinsik untuknya, bagaimanapun, yang akan mempercepatnya secara signifikan.
Cara tercepat untuk melakukan ini tanpanya floorModadalah seperti beberapa jawaban lain di sini, tetapi tanpa cabang bersyarat dan hanya satu %operasi lambat .
Asumsi n positif, dan x bisa berupa apa saja:
int remainder = (x % n); // may be negative if x is negative
//if remainder is negative, adds n, otherwise adds 0
return ((remainder >> 31) & n) + remainder;
Hasil ketika n = 3:
x | result
----------
-4| 2
-3| 0
-2| 1
-1| 2
0| 0
1| 1
2| 2
3| 0
4| 1
Jika Anda hanya memerlukan distribusi seragam antara 0dan n-1dan bukan operator mod yang tepat, dan Anda xtidak mengelompokkan dekat 0, berikut ini akan menjadi lebih cepat, karena ada lebih banyak paralelisme tingkat instruksi dan %komputasi lambat akan terjadi secara paralel dengan yang lain bagian karena tidak bergantung pada hasilnya.
return ((x >> 31) & (n - 1)) + (x % n)
Hasil diatas dengan n = 3:
x | result
----------
-5| 0
-4| 1
-3| 2
-2| 0
-1| 1
0| 0
1| 1
2| 2
3| 0
4| 1
5| 2
Jika masukan acak dalam rentang penuh int, distribusi kedua solusi akan sama. Jika cluster masukan mendekati nol, akan ada terlalu sedikit hasil di n - 1solusi terakhir.