Anda sudah memiliki jawaban cerdas: aritmatika unsigned adalah aritmatika modulo dan oleh karena itu hasilnya akan bertahan, Anda dapat membuktikannya secara matematis ...
Namun, satu hal keren tentang komputer adalah komputer itu cepat. Memang, mereka sangat cepat sehingga menghitung semua kombinasi valid dari 32 bit dimungkinkan dalam jumlah waktu yang wajar (jangan coba dengan 64 bit).
Jadi, dalam kasus Anda, saya pribadi suka membuangnya ke komputer; saya membutuhkan lebih sedikit waktu untuk meyakinkan diri sendiri bahwa program itu benar daripada yang diperlukan untuk meyakinkan diri sendiri daripada bukti matematis yang benar dan bahwa saya tidak mengawasi detail dalam spesifikasi 1 :
#include <iostream>
#include <limits>
int main() {
std::uint64_t const MAX = std::uint64_t(1) << 32;
for (std::uint64_t i = 0; i < MAX; ++i) {
for (std::uint64_t j = 0; j < MAX; ++j) {
std::uint32_t const a = static_cast<std::uint32_t>(i);
std::uint32_t const b = static_cast<std::uint32_t>(j);
auto const champion = (a + (b & 255)) & 255;
auto const challenger = (a + b) & 255;
if (champion == challenger) { continue; }
std::cout << "a: " << a << ", b: " << b << ", champion: " << champion << ", challenger: " << challenger << "\n";
return 1;
}
}
std::cout << "Equality holds\n";
return 0;
}
Ini menghitung melalui semua kemungkinan nilai a
danb
dalam ruang 32-bit dan memeriksa apakah kesetaraan berlaku, atau tidak. Jika tidak, ia mencetak kasus yang tidak berfungsi, yang dapat Anda gunakan sebagai pemeriksaan kewarasan.
Dan, menurut Clang : Kesetaraan berlaku .
Selanjutnya, mengingat bahwa aturan aritmatika adalah bit-width agnostic (di atas int
bit-width), persamaan ini akan berlaku untuk semua tipe integer 32 bit atau lebih yang tidak bertanda tangan, termasuk 64 bit dan 128 bit.
Catatan: Bagaimana kompilator menyebutkan semua pola 64-bit dalam kerangka waktu yang wajar? Itu tidak bisa. Loop dioptimalkan. Kalau tidak, kita semua akan mati sebelum eksekusi dihentikan.
Saya awalnya hanya membuktikannya untuk 16-bit unsigned integers; sayangnya C ++ adalah bahasa yang tidak masuk akal di mana bilangan bulat kecil (bitwidth lebih kecil dari int
) pertama kali dikonversi int
.
#include <iostream>
int main() {
unsigned const MAX = 65536;
for (unsigned i = 0; i < MAX; ++i) {
for (unsigned j = 0; j < MAX; ++j) {
std::uint16_t const a = static_cast<std::uint16_t>(i);
std::uint16_t const b = static_cast<std::uint16_t>(j);
auto const champion = (a + (b & 255)) & 255;
auto const challenger = (a + b) & 255;
if (champion == challenger) { continue; }
std::cout << "a: " << a << ", b: " << b << ", champion: "
<< champion << ", challenger: " << challenger << "\n";
return 1;
}
}
std::cout << "Equality holds\n";
return 0;
}
Dan sekali lagi, menurut Clang : Kesetaraan berlaku .
Nah, ini dia :)
1 Tentu saja, jika suatu program secara tidak sengaja memicu Perilaku Tidak Terdefinisi, itu tidak akan membuktikan banyak.
Math.random()
mengembalikan integer atau double pada [0,1)? Saya tidak berpikir naskah Anda (sebaik yang saya tahu) mencerminkan masalah yang Anda ajukan sama sekali.