Terlepas dari fakta bahwa fungsi hashing Anda tidak terlalu bagus * , masalah terbesar dengan kode Anda bukanlah bahwa ia mengembalikan angka yang berbeda tergantung pada versi .NET, tetapi dalam kedua kasus itu mengembalikan angka yang sama sekali tidak berarti: jawaban yang benar untuk masalah ini adalah
49 103 mod 143 = adalah 114. ( link Wolfram Alpha )
Anda dapat menggunakan kode ini untuk menghitung jawaban ini:
private static int PowMod(int a, int b, int mod) {
if (b == 0) {
return 1;
}
var tmp = PowMod(a, b/2, mod);
tmp *= tmp;
if (b%2 != 0) {
tmp *= a;
}
return tmp%mod;
}
Alasan mengapa perhitungan Anda menghasilkan hasil yang berbeda adalah karena untuk menghasilkan jawaban, Anda menggunakan nilai antara yang menurunkan sebagian besar digit signifikan dari bilangan 49103 : hanya 16 pertama dari 175 digitnya yang benar!
1230824813134842807283798520430636310264067713738977819859474030746648511411697029659004340261471771152928833391663821316264359104254030819694748088798262075483562075061997649
159 digit sisanya semuanya salah. Operasi mod, bagaimanapun, mencari hasil yang membutuhkan setiap digit untuk benar, termasuk yang terakhir. Oleh karena itu, bahkan peningkatan terkecil pada ketepatan Math.Pow
yang mungkin telah diterapkan di .NET 4, akan menghasilkan perbedaan drastis pada penghitungan Anda, yang pada dasarnya menghasilkan hasil yang berubah-ubah.
* Karena pertanyaan ini berbicara tentang menaikkan bilangan bulat menjadi kekuatan tinggi dalam konteks hashing kata sandi, mungkin ide yang sangat baik untuk membaca tautan jawaban ini sebelum memutuskan apakah pendekatan Anda saat ini harus diubah untuk pendekatan yang berpotensi lebih baik.