Di java saat Anda melakukannya
a % b
Jika a negatif, itu akan mengembalikan hasil negatif, alih-alih membungkusnya menjadi b seperti seharusnya. Apa cara terbaik untuk memperbaikinya? Satu-satunya cara saya bisa berpikir adalah
a < 0 ? b + a : a % b
java
modulo
negative-number
fent
sumber
sumber
Jawaban:
Ini berperilaku sebagaimana mestinya a% b = a - a / b * b; yaitu sisanya.
Anda dapat melakukan (a% b + b)% b
Ekspresi ini bekerja karena hasil dari
(a % b)
harus lebih rendah darib
, tidak peduli apakaha
positif atau negatif. Penjumlahanb
menangani nilai negatif daria
, karena(a % b)
merupakan nilai negatif antara-b
dan0
,(a % b + b)
harus lebih rendah darib
dan positif. Modulo terakhir ada jikaa
positif untuk memulai, karena jikaa
positif(a % b + b)
akan menjadi lebih besar darib
. Oleh karena itu,(a % b + b) % b
ubah menjadi lebih kecil darib
lagi (dan tidak mempengaruhia
nilai negatif ).sumber
(a % b)
selalu lebih rendah darib
(tidak peduli apakaha
positif atau negatif), penambahanb
menjaga nilai negatifa
, karena(a % b)
lebih rendah darib
dan lebih rendah dari0
,(a % b + b)
harus lebih rendah darib
dan positif. Modulo terakhir ada jikaa
positif untuk memulai, karena jikaa
positif(a % b + b)
akan menjadi lebih besar darib
. Oleh karena itu,(a % b + b) % b
ubah menjadi lebih kecil darib
lagi (dan tidak mempengaruhia
nilai negatif ).a < 0
, mungkin Anda bisa melihatnya)(a % b + b) % b
pemecahan untuk nilai yang sangat besar daria
danb
. Misalnya, menggunakana = Integer.MAX_VALUE - 1
danb = Integer.MAX_VALUE
akan memberi-3
hasil, yang merupakan angka negatif, yang ingin Anda hindari.while
akan lebih lambat jika Anda benar-benar membutuhkannya kecuali Anda hanya perluif
dalam hal ini sebenarnya lebih cepat.Pada Java 8, Anda dapat menggunakan Math.floorMod (int x, int y) dan Math.floorMod (long x, long y) . Kedua metode ini memberikan hasil yang sama dengan jawaban Petrus.
sumber
float
ataudouble
argumen. Mod binary operator (%
) juga bekerja denganfloat
dandouble
operan.Bagi mereka yang belum menggunakan (atau belum bisa menggunakan) Java 8, Guava datang untuk menyelamatkan dengan IntMath.mod () , tersedia sejak Guava 11.0.
Satu peringatan: tidak seperti Math.floorMod () Java 8, pembagi (parameter kedua) tidak boleh negatif.
sumber
Dalam teori bilangan, hasilnya selalu positif. Saya kira hal ini tidak selalu terjadi dalam bahasa komputer karena tidak semua programmer adalah ahli matematika. Dua sen saya, saya akan menganggapnya sebagai cacat desain bahasa, tetapi Anda tidak dapat mengubahnya sekarang.
= MOD (-4.180) = 176 = MOD (176, 180) = 176
karena 180 * (-1) + 176 = -4 sama dengan 180 * 0 + 176 = 176
Menggunakan contoh jam di sini, http://mathworld.wolfram.com/Congruence.html Anda tidak akan mengatakan durasi_of_time mod cycle_length adalah -45 menit, Anda akan mengatakan 15 menit, meskipun kedua jawaban memenuhi persamaan dasar.
sumber
-1
daripadan-1
misalnya) kemudian lakukan itu.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
floorMod
adalah seperti beberapa jawaban lain di sini, tetapi tanpa cabang bersyarat dan hanya satu%
operasi lambat .Asumsi n positif, dan x bisa berupa apa saja:
Hasil ketika
n = 3
:Jika Anda hanya memerlukan distribusi seragam antara
0
dann-1
dan bukan operator mod yang tepat, dan Andax
tidak mengelompokkan dekat0
, 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
:Jika masukan acak dalam rentang penuh int, distribusi kedua solusi akan sama. Jika cluster masukan mendekati nol, akan ada terlalu sedikit hasil di
n - 1
solusi terakhir.sumber
Berikut ini alternatifnya:
Ini mungkin atau mungkin tidak lebih cepat dari rumus lain [(a% b + b)% b]. Tidak seperti rumus lainnya, rumus ini berisi cabang, tetapi menggunakan satu operasi modulo yang lebih sedikit. Mungkin menang jika komputer dapat memprediksi <0 dengan benar.
(Edit: Memperbaiki rumus.)
sumber